
約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
など。
私は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
cshbash
に似ていない他のシェルで)使用:
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
bash
ファイル名に改行文字が含まれていない場合は、POSIXシェルで機能します。
答え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