我有大约 100 个文件。
他们的名字是这样的。
3000_ABCD_XXXXXXX.csv
3000_ABCD_YYYYYYY.csv
3000_ABCD_XYXYZYZ.csv
3000_EFGH_XXXXXXX.csv
3000_EFGH_YYYYYYY.csv
3000_EFGH_XYXYZYZ.csv
3000_IJKL_XXXXXXX.csv
3000_IJKL_YYYYYYY.csv
3000_IJKL_XYXYZYZ.csv
目前,我正在单独压缩每个文件,但我想根据它们的公共子字符串对它们进行分组,例如ABCD.zip
将存储
3000_ABCD_XXXXXXX.csv
3000_ABCD_YYYYYYY.csv
3000_ABCD_XYXYZYZ.csv
EFGH.zip
将存储
3000_EFGH_XXXXXXX.csv
3000_EFGH_YYYYYYY.csv
3000_EFGH_XYXYZYZ.csv
ETC。
我对 Unix/Bash 脚本非常陌生。有人能指出我正确的方向吗?
编辑:ABCD
、EFGH
、IJKL
事先不知道。不过,它们在文件名中的位置和宽度是有保证的。
答案1
和zsh
:
setopt extendedglob
typeset -A a
for f (./*) {
[[ $f = (#b)*_(*)_* ]] &&
a[$match]+=$f$'\0'
}
for z (${(k)a}) {
echo zip ./$z.zip ${(ps:\0:)a[$z]}
}
(删除 ,echo
满意后实际执行)。
使用perl
(来自zsh
/bash
或任何其他非类 csh 的 shell):
perl -e 'for (@ARGV) {push @{$a{$1}}, $_ if (/_(.*)_/s)}
system "echo", "zip", "./$_.zip", @{$a{$_}} for (keys %a)' ./*_*_*
(再次,删除 来"echo",
实际执行)。
答案2
你可以这样做:
IFS='
'
set -f
for group in $(set +f; printf '%s\n' 3000_*.csv | sed 's/3000_\([^_]*\).*/\1/' | LC_ALL=C uniq)
do
set +f
zip "$group.zip" "3000_$group"*.csv
done
应该可以在 POSIX shell 中工作bash
,前提是文件名不包含换行符。
答案3
您可以尝试下面的脚本。
##The find command below finds all the csv files in the current directory.
find ~/home/file-directory-location/*.csv -type f > filenames.txt
##We know the second substring after _ will contain the index.
##I am sorting the file based on that second substring and getting the
##indices into a new file for zipping.
##The uniq will specify how many zip files we are creating.
LC_ALL=C sort -t_ -k2,2 filenames.txt | cut -d '_' -f 2 | LC_ALL=C uniq > indexes
##Now, for the created indices just zip the CSV files based on the index name.
while read index;
do
tar cvzf "$index".tgz /home/file-directory-location/3000_"$index"*
done <indexes