filename~contenturl~uuid~nodeid~contentid
000224.pdf~store://2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin~d6203724-1100-4057-9ed5-4ca6a94f5512~1324625~1363256
000238.pdf~store://2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin~96b7343d-349d-4316-8bc6-def5bd924032~1324641~1363292
000262.pdf~store://2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin~11827eee-67bb-43b7-a743-966514f26457~1324661~1363375
위는 구분 기호 "~"가 있는 .csv 파일입니다. store://에서 시작하는 두 번째 열의 하위 문자열을 만들고 해당 행의 체크섬 결과를 동일한 열에 추가하려고 합니다. 새 열은 가능하면 CSV를 사용합니다.
예를 들어
filename~contenturl~checksum
000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 23423423425
따라서 최종 결과가 표시되면 store://의 경로 부분 문자열을 만들고 해당 파일에 대한 체크섬이라는 새 열을 추가합니다.
쉘 스크립트를 통해 bin/bash를 사용하고 싶습니다
======================== 내 경우에는 방금 AWK를 사용해 보았지만 다음을 사용하여 첫 번째와 두 번째 열 값만 얻을 수 있었습니다.
awk -F "~" '{print $1, $2}' $csv_file
이제 다음 작업은 복잡합니다. 두 번째 열 값에는 텍스트 처리가 필요하고체크섬넌 합격할 수 있어
cksum /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin
네, 제대로 들었습니다. 최종 결과는 다음과 같습니다.
filename~contenturl~checksum
000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 23423423425
다른 열의 나머지 부분도 있으면 더 좋을 것입니다. 그렇지 않으면 상위 3개 열도 괜찮을 것입니다. 참고: 기존 열을 유지하고 "체크섬"이라는 열을 더 추가해도 괜찮습니다.
답변1
해결 방법을 좀 더 쉽게 만들고 헤더 줄이 일관되지 않기 때문에(입력 파일의 줄바꿈이 잘못되고 ~
출력 파일의 구분 기호가 잘못됨) 입력 파일에 헤더 줄이 없다고 가정해 보겠습니다.
이 작업은 다음 두 단계로 해결할 수 있습니다.
파일 을 만들려면
checksums.csv
파일 경로만 있으면 됩니다.awk -F'~' '{ system("cksum /opt/xyz"substr($2,8)) }' file.csv > checksums.csv
substr($2,8)
접두사를 제거store:/
하고/opt/xyz
앞에 추가하여 경로를 완성합니다. 이system(…)
명령은 지정된 경로에서 명령을 실행cksum
하고 출력을 출력 파일로 리디렉션합니다.샘플 출력은 다음과 같습니다.
$ cat checksums.csv 128361894 41 /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 820470222 41 /opt/xyz/2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin 1593587341 41 /opt/xyz/2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin
출력에는 체크섬, 바이트 수, 경로의 3개 열이 포함되어 있으므로 다음 단계에서 세 번째와 첫 번째 열을 추출해야 합니다.
헤더 행을 인쇄하고 컬럼 1(파일 이름)을
file.csv
컬럼 3(경로) 및 컬럼 1(체크섬)과 병합합니다checksums.csv
.{ echo "filename contenturl checksum";\ paste -d ' ' <(awk -F'~' '{ print $1 }' file.csv) <(awk '{ print $3,$1 }' checksums.csv);\ } > newfile.csv
출력 예:
$ cat newfile.csv filename contenturl checksum 000224.pdf /opt/xyz/2018/7/20/11/35/3f176f4b-41a0-4ac4-a795-a2240ffbb7b9.bin 128361894 000238.pdf /opt/xyz/2018/7/20/11/35/4302b390-1134-424d-a92f-ad27b233e8c1.bin 820470222 000262.pdf /opt/xyz/2018/7/20/11/35/5ff59679-b3ec-46d2-aa7d-5ec28eff6fe9.bin 1593587341
그런 다음 정리하십시오.
rm checksums.csv
답변2
GNU에는 스크립트처럼 쉘 처리를 통합할 수 있는 명령 플래그가 sed
있습니다 .e
s
cksum
sed -E 'h;s_.*~store:/([^~]*).*_cksum /opt/xyz\1_e;x;G;s_~[^~]*(.*)\n(.*) .* (.*)_~\2~\3\1_;s/~/ /g'
-E
가독성을 높이기 위해 확장 정규식으로 전환하는 옵션h
현재 행을 예약된 공간에 저장하여 원하는 대로 처리할 수 있습니다.s_.*~store:/([^~]*).*_cksum /opt/xyz\1_e
store:/
(제거할),()
재사용할 파일 이름\1
및 나머지 줄(제거할)을 포함한 모든 항목을 일치시키고cksum
+ 경로로 바꿉니다. 이제e
플래그가 이 명령을 실행하고 패턴 공간을 반환된 내용으로 바꾸기 시작합니다.x;G
홀드 공간과 패턴 공간을 바꾼 다음 패턴 공간에 홀드를 추가하여 버퍼에 다음이 포함되도록 합니다.s_~[^~]*(.*)\n(.*) .* (.*)_~\2~\3\1_
읽어야 할 수도 있지만 쓰기 쉽습니다.~[^~]*
두 번째 필드,(.*)\n
원래 줄의 나머지 부분,(.*) .* (.*)
세 개의 필드가 반환되므로cksum
두 번째 필드는 파일 이름과 체크섬으로 대체됩니다.- 질문에 쓰지 않았지만 예에는
~
구분 기호가 없지만 공백이 두 개 있습니다.s/~/ /g