여러 하위 디렉터리가 있는 디렉터리가 있습니다. 가지다압축파일에 대한 질문여기에는 내 필요에 맞게 약간 수정한 답변이 포함되어 있습니다.
for i in */; do zip "zips/${i%/}.zip" "$i*.csv"; done
그런데 이상한 문제에 부딪혔습니다. 존재하지 않는 첫 번째 폴더 세트의 경우 zips/<name>.zip
다음 오류가 발생합니다.
zip error: Nothing to do! (zips/2014-10.zip)
zip warning: name not matched: 2014-11/*.csv
하지만그냥 echo
zip 명령문을 사용하는 경우:
for i in */; do echo zip "zips/${i%/}.zip" "$i*.csv"; done
그런 다음 echo 명령( zip zips/2014-10.zip 2014-10/*.csv
)을 실행했는데 제대로 작동하고 폴더가 압축되었습니다. 흥미로운 부분은 원래 명령의 후속 실행입니다.~ 할 것이다처음에는 작동하지 않았던 폴더를 압축하는 것이 실제로 가능합니다!
이 동작을 직접 테스트하려면 다음을 수행하세요.
cd /tmp
mkdir -p 2016-01 2016-02 2016-03 zips
for i in 2*/; do touch "$i"/one.csv; done
for i in 2*/; do touch "$i"/two.csv; done
zip zips/2016-03.zip 2016-03/*.csv
for i in 2*/; do echo zip "zips/${i%/}.zip" "$i*.csv"; done
for i in 2*/; do zip "zips/${i%/}.zip" "$i*.csv"; done
echo가 다음 명령문을 인쇄하는 것을 볼 수 있습니다.
zip zips/2016-01.zip 2016-01/*.csv
zip zips/2016-02.zip 2016-02/*.csv
zip zips/2016-03.zip 2016-03/*.csv
그러나 실제 zip 명령은 다음을 알려줍니다.
zip warning: name not matched: 2016-01/*.csv
zip error: Nothing to do! (zips/2016-01.zip)
zip warning: name not matched: 2016-02/*.csv
zip error: Nothing to do! (zips/2016-02.zip)
updating: 2016-03/one.csv (stored 0%)
updating: 2016-03/two.csv (stored 0%)
.csv
따라서 실제로는 zip 파일이 들어 있는 s로 zip 파일을 업데이트하지만아니요zip 파일을 생성할 때. zip 명령 중 하나를 복사하는 경우:
$ zip zips/2016-02.zip 2016-02/*.csv
adding: 2016-02/one.csv (stored 0%)
adding: 2016-02/two.csv (stored 0%)
그런 다음 zip-all-the-things를 다시 실행하십시오.
for i in 2*/; do zip "zips/${i%/}.zip" "$i*.csv"; done
2016-02
및 에 대해 업데이트된 것을 볼 수 있습니다 2016-03
. 이것은 내 결과입니다 tree
.
.
├── 2016-01
│ ├── one.csv
│ └── two.csv
├── 2016-02
│ ├── one.csv
│ └── two.csv
├── 2016-03
│ ├── one.csv
│ └── two.csv
└── zips
├── 2016-02.zip
└── 2016-03.zip
또한 놀랍게도 이것은 잘 작동합니다.
zsh -c "$(for i in 2*/; do echo zip "zips/${i%/}.zip" "$i*.csv"; done)"
내가 여기서 뭘 잘못하고 있는 걸까? (참고로 저는 bash 대신 zsh를 사용하고 있습니다. 차이가 있다면)
답변1
쉘을 통한 확장
주변 인용문이 "$i*.csv"
다릅니다. 따옴표를 사용하면 셸은 문자열을 "2014-11/*.csv"로 확장합니다. 정확한 파일이 존재하지 않으며 zip
오류가 보고됩니다. 따옴표가 없으면 *
확장도 수행되며(파일 이름 확장/"globbing"을 통해) 결과 zip
명령은 각각 별도의 인수로 일치하는 파일의 전체 목록입니다. 다음을 사용하여 루프 내에서 두 번째 동작을 얻을 수 있습니다 for
.
for i in */ ; do zip "zips/${i%/}.zip" "$i"*.csv ; done
zip 확장을 통해
zip
와일드카드를 자체적으로 확장하는 것도 가능하지만 모든 경우에 그런 것은 아닙니다. ~에서지퍼 수동:
이것압축프로그램은 다음의 이름에 대해 동일한 일치를 수행할 수 있습니다.압축아카이브가 수정되었거나,-엑스(제외) 또는-나(include) 옵션은 작업할 파일 목록에 백슬래시나 따옴표를 사용하여 이름 확장을 수행하지 않도록 쉘에 지시합니다.
아카이브를 성공적으로 생성한 후 원래 명령은 zip
기존 아카이브의 내용과 와일드카드를 일치시키려고 시도하므로 후속 시도에서 작동합니다. 그것들은 거기에 존재했고 여전히 파일 시스템에 존재하므로 결국 updating:
.
zip
와일드카드를 얻으려면만들다-r
(recurse) 옵션을 사용하여 요청된 디렉터리로 재귀적으로 보관 하고 -i
패턴과 일치하는 파일로 제한(포함)합니다.
for i in */ ; do zip -r "zips/${i%/}.zip" "$i" -i '*.csv' ; done