以日期命名的目录中有 n 文件夹,例如:
20171002 20171003 20171005 ... 20171101 20171102 20171103 ... 20180101 20180102
提示:日期不是连续的。 我想将每个月的每三个文件夹压缩成一个压缩块。 例如:
tar jcvf mytar-20171002_1005.tar.bz2 20171002 20171003 20171005
如何编写shell来执行此操作?
答案 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