如何编写shell脚本为文件名中具有相同字符串的文件创建zip文件

时间:2014-05-02 12:17:35

标签: linux bash shell

如何编写简单的shell脚本来创建zip文件 我想通过从文件夹中收集文件名中具有相同字符串模式的文件来创建zip文件。

例如,文件夹下可能有许多文件。

  • xxxxx_20140502_xxx.txt
  • xxxxx_20140502_xxx.txt
  • xxxxx_20140503_xxx.txt
  • xxxxx_20140503_xxx.txt
  • xxxxx_20140504_xxx.txt
  • xxxxx_20140504_xxx.txt

运行shell脚本后,结果必须是三个zip文件。

  • 20140502.zip
  • 20140503.zip
  • 20140504.zip

请给我正确的方向来创建简单的shell脚本以输出上面的结果。

3 个答案:

答案 0 :(得分:1)

#!/bin/bash

for file in *_????????_*.csv *_????????_*.txt; do
        [ -f "${file}" ] || continue
        date=${file#*_}  # adjust this and next line depending
        date=${date%_*}  # on your actual prefix/suffix
        echo "${date}"
done | sort -u | while read date; do
        zip "${date}.zip" *${date}*
done

答案 1 :(得分:1)

由于zip将更新存档,因此会执行以下操作:

shopt -s nullglob
for file in *.{txt,csv}; do [[ $file =~ _([[:digit:]]{8})_ ]] && zip "${BASH_REMATCH[1]}.zip" "$file"; done

shopt -s nullglob是因为如果没有匹配的文件,您不想拥有未展开的整数。


这一行以下的一切都是我的老答案......

首先,获取所有可能的日期。启发式地,这可能是以.txt.csv结尾的文件,与正则表达式_[[:digit:]]{8}_匹配:

#!/bin/bash
shopt -s nullglob
declare -A dates=()
for file in *.{csv,txt}; do
    [[ $file =~ _([[:digit:]]{8})_ ]] && dates[${BASH_REMATCH[1]}]=
done
printf "Date found: %s\n" "${!dates[@]}"

这将输出到stdout文件中找到的所有日期。例如。 (我调用了之前的剪切gorilla和我chmod +x gorilla并触摸了几个文件进行演示):

$ ls
banana_20010101_gorilla.csv  gorilla_20140502_bonobo.csv
gorilla                      notthisone_123_lol.txt
gorilla_20140502_banana.txt
$ ./gorilla
Date found: 20140502
Date found: 20010101

下一步,对于找到的每个日期,在与日期对应的存档中获取以.txt.csv以及zip结尾的所有文件:将其附加到{{1}将完成这项工作:

gorilla

删除泛滥部分后的完整脚本:

for date in "${!dates[@]}"; do
    zip "$date.zip" *"_${date}_"*.{csv,txt}
done

编辑。我用一行命令忽略了你的要求。那么这就是单线:

#!/bin/bash
shopt -s nullglob
declare -A dates=()
for file in *.{csv,txt}; do
    [[ $file =~ _([[:digit:]]{8})_ ]] && dates[${BASH_REMATCH[1]}]=
done
for date in "${!dates[@]}"; do
    zip "$date.zip" *"_${date}_"*.{csv,txt}
done

shopt -s nullglob; declare -A dates=(); for file in *.{csv,txt}; do [[ $file =~ _([[:digit:]]{8})_ ]] && dates[${BASH_REMATCH[1]}]=; done; for date in "${!dates[@]}"; do zip "$date.zip" *"_${date}_"*.{csv,txt}; done

答案 2 :(得分:0)

#! /bin/bash
dates=$(ls ?????_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_???.{csv,txt} \
    | cut -f2 -d_ | sort -u)

for date in $dates ; do
    zip $date.zip ?????_"$date"_???.{csv,txt}
done