압축을 풀고 싶은 아주 큰 zip 파일(~10GB)이 있고 그 결과는 두 개의 명령으로 전달되어야 합니다. 두 후속 명령의 결과는 파일에 추가되어야 하며
현재 나는 달리고있다
unzip -p bigFile.zip | head -n 1 >> output.txt
unzip -p bigFile.zip | grep -v 'skipLine' >> output.txt
이것은 약 백만 개의 행을 제공합니다. 이제 1행으로 하고 싶습니다. 나는 사용하기 tee
시작했다
unzip -p bigFile.zip | tee >(head -n 1 >> output.txt) >(grep -v 'skipLine'
>> output.txt)
그러나 output.txt
파일에는 51줄만 포함되어 있으며 그 중 마지막 줄은 완전하지도 않습니다. 또한 후자의 명령은 내가 원하지 않는 결과를 터미널에 인쇄합니다.
나도 시도했다
unzip -p bigFile.zip | tee >(head -n 1 >> output.txt) | grep -v 'skipLine'
>> output.txt
그러나 불행히도 이것도 작동하지 않습니다.
어떤 도움이라도 대단히 감사하겠습니다! 를 사용할 필요가 없습니다 . 위젯의 출력을 and 명령 에 tee
전달할 수 있는 한 다른 명령은 잘 작동합니다 .unzip
head
grep
편집하다:head
및 명령의 출력을 "결합"한 다음 에 전달할 수 있다면 grep
훨씬 더 좋을 것입니다 zip
. 가능합니까?
답변1
첫 번째 줄을 가져와 인쇄하고 grep이 나머지를 사용할 수 있도록 하는 쉘 스크립트의 압축을 풀고 파이프할 수 있습니다.
unzip -p bigFile.zip | {
IFS= read -r header # consume the first line, verbatim
printf "%s\n" "$header"
grep -v 'skipLine'
} >> output.txt
블록에서 인쇄된 모든 내용은 출력 파일에 추가됩니다.
답변2
두 개의 개별 명령을 파이프하는 방법은 생각할 수 없지만 다음을 사용할 수 있습니다 awk
.
unzip -p file.zip | awk 'NR==1 || !/skipLine/' > output
NR==1
awk 명령은 현재 행이 첫 번째 행( )이거나 일치하지 않는 경우 skipline
( )를 인쇄합니다.!/skipLine
내가 생각할 수 있는 가장 좋은 조합 grep
은 다음과 같습니다 head
.
unzip -p file.zip | tee >(head -n1 > output) | tail -n+2 | grep -v skipLine >> output
아이디어는 첫 번째 줄을 먼저 캡처한 다음 head -n1
다음을 사용하여 tail -n+2
첫 번째 줄을 제외한 모든 것을 인쇄하는 것입니다.grep
awk
답변3
미묘한 점이 빠졌을 수도 있지만 첫 번째 줄을 유지하고 첫 번째 줄 이후에 고유한 텍스트가 포함되지 않은 내용을 유지하려는 것 같습니다 skipLine
. sed
이 일을 잘 처리할 것 같습니다 .
#!/bin/bash
sed -n '1 {p;d} #for line 1, print and discard
/skipLine/d #delete any line with skipLine
p #print remainder
' << End_of_SampleData
head
prefix skipLine
keepLine
skipLine suffix
keepLine
End_of_SampleData
산출:
head
keepLine
keepLine
unzip -p bigFile.zip | sed ...
이 테스트 사례가 요구 사항을 충족하는 경우 데이터를 이 스크립트로 파이프할 수 있습니다. 실행할 프로세스 는 단 unzip
하나 뿐이므로 속도가 빨라야 합니다 .sed
답변4
명령에 두 가지 문제가 발생합니다 tee
.
tee >(head -n 1 >>output.txt) >(grep -v 'skipLine' >>output.txt)
가장 간단한 것은 출력을 삭제하려는 경우입니다. 이렇게 하려면 간단히 표준 출력을 /dev/null로 보내면 됩니다.
tee >(head -n 1 >>output.txt) >(grep -v 'skipLine' >>output.txt) >/dev/null
그러나 이것은 낭비적인 것처럼 보입니다. tee
두 번째 명령을 표준 출력에 연결하는 것이 더 효율적입니다.
tee >(head -n 1 >>output.txt) | grep -v 'skipLine' >>output.txt
두 번째는 head
필요한 입력을 읽은 후 닫는 것입니다. 간단한 수정은 입력을 삭제하는 절차를 사용하는 것입니다.
tee >(head -n 1 >>output.txt; dd of=/dev/null) | grep -v skipLine >>output.txt
이 파이프가 이전 콘텐츠를 대체하도록 하려면 두 개의 열기를 output.txt
하나로 바꿀 수 있습니다.
exec 3>output.txt
tee >(head -n 1 >&3; dd of=/dev/null) | grep -v skipLine >&3
두 개의 독립 파이프가 있는 초기 버전과 달리 이러한 모든 버전에서는 헤더 행이 출력 파일의 시작 부분에 있다는 보장이 없습니다. 이것이 요구 사항인 경우 교체에 대한 다른 답변 중 하나를 확인하십시오(또는 sleep
이전 시퀀스를 사용한 도박 grep
).
하지만 이 답변이 도움이 되었으면 좋겠습니다이해하다왜 숟가락으로 떠먹여주는 대안 대신 자신이 하는 일의 결과를 볼 수 있을까요?