如何使用shell一次压缩多个文件夹?

时间:2018-04-13 10:47:26

标签: bash shell ubuntu for-loop

以日期命名的目录中有 n 文件夹,例如:

20171002 20171003 20171005 ... 20171101 20171102 20171103 ... 20180101 20180102

提示:日期不是连续的。 我想将每个月的每三个文件夹压缩成一个压缩块。 例如:

tar jcvf mytar-20171002_1005.tar.bz2 20171002 20171003 20171005

如何编写shell来执行此操作?

4 个答案:

答案 0 :(得分:0)

您需要在ls变量上执行for循环,然后解析目录名称。

dir_list=$(ls)
prev_month=""
times=0
first_dir=""
last_dir=""
dir_list=()
for i in $dir_list; do 
   month=${i:0:6} #here month will be year plus month
   if [ "$month" = "$prev_month" ]; then 
      i=$(($i+1))
      if [ "$i" -eq "3" ]; then 
          #compress here 
          dir_list=()
          first_dir=""
          last_dir=""
      else 
          last_dir=$i
          dir_list+=($i)
      fi
   else
     if [ "$first_dir" = "" ]; then 
         first_dir=$i
     else 
         #compress here 
         first_dir="$i"
         last_dir=""
         dir_list=()
     fi 
   fi

此代码未经过测试,可能包含语法错误。 '#compress here'需要由数组上的循环替换以创建要压缩的字符串。

答案 1 :(得分:0)

假设您没有太多目录(我认为限制是几百个),那么您可以使用Bash的数组操作。

因此,首先将所有目录名称加载到Bash数组中:

dirs=( $(ls) )

(我假设文件名称中没有空格,否则会有点冒险)

然后你可以使用Bash的数组切片语法一次从数组中弹出3个元素:

while [ "${#dirs[@]}" -gt 0 ]; do
    dirs_to_compress=( "${dirs[@]:0:3}" )
    dirs=( "${dirs[@]:3}" )
    # do something with dirs_to_compress
done

剩下的应该很容易。

答案 2 :(得分:0)

unset folders
declare -A folders
g=3
for folder in $(ls -d */); do
    folders[${folder:0:6}]+="${folder%%/} "
done
for folder in "${!folders[@]}"; do
    for((i=0; i < $(echo ${folders[$folder]} | tr ' ' '\n' | wc -l); i+=g)) do
        group=(${folders[$folder]})
        groupOfThree=(${group[@]:i:g})
        tar jcvf mytar-${groupOfThree[0]}_${groupOfThree[-1]:4:4}.tar.bz2 ${groupOfThree[@]}
    done
done

此脚本查找当前目录中的所有文件夹,将它们分成几个月组,创建最多三个文件夹的组,并为每个文件夹创建一个 .tar.bz2 ,并使用您使用的名称在问题中。

我用这些文件夹测试了它:

20171101 20171102 20171103  20171002 20171003 20171005 20171007 20171009 20171011 20171013  20180101 20180102

创建的焦油是:

mytar-20171002_1005.tar.bz2
mytar-20171007_1011.tar.bz2
mytar-20171013_1013.tar.bz2
mytar-20171101_1103.tar.bz2
mytar-20180101_0102.tar.bz2

希望有所帮助:)

编辑:如果您使用的是bash版本&lt; 4.2然后更换行:

tar jcvf mytar-${groupOfThree[0]}_${groupOfThree[-1]:4:4}.tar.bz2 ${groupOfThree[@]}

由:

tar jcvf mytar-${groupOfThree[0]}_${groupOfThree[`expr ${#groupOfThree[@]} - 1`]:4:4}.tar.bz2 ${groupOfThree[@]}

那是因为bash版本&lt; 4.2不支持数组的负索引。

答案 3 :(得分:0)

您可以使用xargs,bash while循环和awk实现此目的:

ls | xargs -n3 | while read line; do
    tar jcvf $(echo $line | awk '{print "mytar-"$1"_"substr($NF,5,4)".tar.bz2"}') $line
done