약 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
/ bash
또는 csh와 유사하지 않은 다른 쉘에서) 사용 :
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