Bash: 공통 하위 문자열로 파일 압축/그룹화

Bash: 공통 하위 문자열로 파일 압축/그룹화

약 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

관련 정보