
내 요구 사항의 첫 번째 부분:
나는 그것에서 단일 파일을 추출하고 싶습니다 ex1234.zip
. 구조 및 내용 ex1234.zip
:
ex1234 (directory)
directory1
ex1234 (directory)
directory2
ex1234.csv
파일 만 추출하고 싶지만 ex1234.csv
이름을 모릅니다.
두 번째 부분은 exXXXX.zip
동일한 디렉터리의 모든 항목에 대해 이 작업을 수행할 수 있다는 것입니다.
ex1234.zip
ex3245.zip
ex8829.zip
exXXXX.zip…
출력은 다음과 같습니다:
ex1234.csv
ex3245.csv
ex8829.csv
exXXXX.csv
실제 샘플:
$ 덜CW2178470.zip 아카이브: CW2178470.zip Zip 파일 크기: 26108바이트, 항목 수: 26 -rw---- 2.0 fat 108 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470.csv -rw---- 2.0 fat 1363 bl defN 15-Aug-04 09:37 CW2178470/config/BusinessContactApprovers.csv -rw---- 2.0 fat 158 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/announcements.xml -rw---- 2.0 fat 1037 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/Plan/plan.xml -rw---- 2.0 fat 141 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/Plan/tasks.xml -rw---- 2.0 fat 2408 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/FI_Doc208411460_doc.xml -rw---- 2.0 fat 215 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/MessageBoard/nb_27482kst.26ihyzj_.htm -rw---- 2.0 fat 2364 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/MessageBoard/messageboard.xml -rw---- 2.0 fat 1250 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/team.xml -rw---- 2.0 fat 22016 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/Doc208411460.doc -rw---- 2.0 fat 9973 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/audistory.xml -rw---- 2.0 fat 6731 bl defN 2004년 8월 15일 09:37 CW2178470/CW2178470/ws.xml -rw---- 2.0 fat 308 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/WSFolder.xsd -rw---- 2.0 fat 4897 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/Task.xsd -rw---- 2.0 fat 770 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/ContractWorkspace.xsd -rw---- 2.0 fat 4754 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/AuditHistory.xsd -rw---- 2.0 fat 25564 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/CommonTypes.xsd -rw---- 2.0 fat 5657 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/MessageBoard.xsd -rw---- 2.0 fat 2471 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/Plan.xsd -rw---- 2.0 fat 337 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/InternalContractWorkspace.xsd -rw---- 2.0 fat 1045 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/SalesContractRequest.xsd -rw---- 2.0 fat 3133 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/FolderItem.xsd -rw---- 2.0 fat 906 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/ContractRequest.xsd -rw---- 2.0 fat 8973 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/WorkspaceTypes.xsd -rw---- 2.0 fat 4645 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/Team.xsd -rw---- 2.0 fat 781 bl defN 2004년 8월 15일 09:37 CW2178470/xsd/SalesContractWorkspace.xsd 26개 파일, 112005바이트 비압축, 21940바이트 압축: 80.4% (끝)
답변1
다음과 같이 사용할 수 있습니다 unzip
.
unzip -j file[.zip] [file] [-x xfile]
여기서 는 -j
휴지통 경로를 나타내고, file[.zip]
는 아카이브 이름, [file]
는 처리할 아카이브 멤버, [-x xfile]
는 처리에서 제외할 아카이브 멤버 목록입니다. 이러한 모든 옵션은 매뉴얼 페이지에 자세히 설명되어 있습니다.
따라서 귀하의 경우에는 다음과 같이 실행하십시오.
unzip -j ex1234.zip '*/*.csv' -x '*/*/*'
*.csv
깊이 수준 2와 일치하는 아카이브의 모든 파일은 현재 디렉터리에서 추출됩니다 ( 경로가 최소 2개 이상 일치하므로 ex1234.zip
깊이 수준 3 이하의 아카이브 구성원 제외 ).'*/*/*'
/
이제 현재 디렉터리의 모든 아카이브를 처리하려면 다음을 실행할 수 있습니다.
for zipfile in *.zip; do unzip -j "$zipfile" '*/*.csv' -x '*/*/*'; done
.csv
현재 디렉터리의 모든 아카이브에서 파일을 추출합니다(그래서 -j
필요한 것입니다).
특정 경우에는 레벨 1 깊이가 없으므로 .csv
다음을 실행할 수도 있습니다.
for zipfile in *.zip; do unzip -j "$zipfile" '*.csv' -x '*/*/*'; done
이렇게 하면 동일한 결과가 생성됩니다.
실행을 테스트하고 실제로 추출하지 않고 어떤 파일(아카이브 경로)이 추출되는지 확인하려면 다음 -j
으로 바꾸십시오 -qql
.
for zipfile in *.zip; do unzip -qql "$zipfile" '*/*.csv' -x '*/*/*'; done
참고로 이 -j
옵션은 생략 가능만약에 그리고 만약에추출할 파일은 .csv
깊이 수준 1에 있습니다(즉, 상위 디렉터리가 없음). 이 경우 간단히 다음을 실행할 수 있습니다.
for zipfile in *.zip; do unzip "$zipfile" '*.csv' -x '*/*'; done
답변2
데비안에서 제공하는 압축 해제를 사용해 보세요:
UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.
for file in ex*.zip
do
unzip -j $file '*.csv'
done
답변3
사용하다퓨즈파일 시스템을 기반으로 하는 디렉터리 트리로 zip 파일에 액세스합니다. 각 zip 파일을 마운트하고 cp
일반적인 방법(셸 와일드카드, 명령 등)을 사용하여 액세스합니다.
그리고퓨즈 지퍼:
mkdir mnt
for z in *.zip; do
fuse-zip -- "$z" mnt
set mnt/*.csv
if [ $# -gt 1 ]; then
echo "Skipping $z because it contains multiple .csv files"
elif ! [ -e "$1" ]; then
echo "Skipping $z because it does not contain a .csv file"
else
cp -- "$1" "${z%.zip}.csv"
fi
fusermount -u mnt
done
같은 방법을 사용하시면 됩니다archivemount
바꾸다 fuse-zip
.
게다가AVFS다르게 작동합니다. 이 보기에서는 전체 파일 시스템에 대한 보기를 생성합니다. ~/.avfs
아카이브 파일이 있는 경우 /path/to/foo.zip
이름 아래의 디렉터리로 액세스할 수 있습니다 ~/.avfs/path/to/foo.zip#
.
mountavfs
cd "$HOME/.avfs$PWD"
for z in *.zip; do
set -- "$z#/"*.csv
if [ $# -gt 1 ]; then
echo "Skipping $z because it contains multiple .csv files"
elif ! [ -e "$1" ]; then
echo "Skipping $z because it does not contain a .csv file"
else
cp "$1" "${z%.zip}.csv"
fi
done
배열이 있는 셸을 사용하고 와일드카드가 일치하지 않을 때 빈 목록을 얻는 방법을 사용하면 약간 더 읽기 쉬운 스크립트를 얻을 수 있습니다. 예를 들어 ksh93에서는 fusion-zip을 사용합니다.
#!/bin/ksh
mkdir mnt
for z in *.zip; do
fuse-zip -- "$z" mnt
csv=(~(N)"$z/"*.csv)
if ((${#csv[@]} > 1)); then
echo "Skipping $z because it contains multiple .csv files"
elif ((${#csv[@]} == 0)); then
echo "Skipping $z because it does not contain a .csv file"
else
cp -- "$1" "${z%.zip}.csv"
fi
fusermount -u mnt
done
zsh에서는 를 사용하고 csv=($z/*.csv(N))
bash에서는 csv=($z/*.csv)
먼저 실행하십시오 shopt -s nullglob
.
답변4
모든 파일이 이 패턴과 일치한다고 가정하면 CW2178470.zip
항상 다음에서 추출해야 합니다.CW2178470/CW2178470.csv
이는 비교적 쉽습니다.
for i in ./*.zip
do
SERIAL=$(echo "$i" | sed -e 's,^.*/,,' -e 's,.zip$,,' )
unzip "$i" "${SERIAL}/${SERIAL}.csv"
done
이보다 더 똑똑한 논리가 필요하다면 아마도 그것을 살펴보고 추출할 것 perl
입니다 Archive::Zip
.