Bash 쉘에서 sed/awk를 사용하여 .tsv 파일의 s3 버킷 경로에 큰따옴표를 추가하는 방법

Bash 쉘에서 sed/awk를 사용하여 .tsv 파일의 s3 버킷 경로에 큰따옴표를 추가하는 방법

.tsvs3 버킷에 대한 소스 및 대상 정보가 포함된 파일이 있습니다 . 나는 이 파일에서 소스 및 대상 경로를 읽고 s3 cp작업을 수행하기 위해 while 루프를 사용하고 있습니다. 이 파일에는 100,000개의 라인이 포함되어 있습니다.

sed명령을 사용하여 파일의 모든 소스 및 대상 경로를 큰따옴표( )로 만드는 방법 xx.tsv. aws s3에서는 공백이 포함된 파일/폴더 이름을 처리할 수 없기 때문에 큰따옴표가 필요합니다 "".

변경할 다음 3줄과 같은 것을 찾고 있습니다.

s3://data01/repo01/image live01.png s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png s3://Ata03/vol01/image live01.png

도착하다

"s3://data01/repo01/image live01.png" "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png" "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png" "s3://Ata03/vol01/image live01.png"

답변1

모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.

$ awk -F'\t' -v OFS='"\t"' '{print "\"" $1, $2 "\""}' file
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

위의 내용은 파일 이름에 탭, 줄 바꿈 또는 큰따옴표가 포함되어 있지 않다고 가정합니다.

답변2

$ cat input.tsv 
s3://data01/repo01/image live01.png     s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png     s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png     s3://Ata03/vol01/image live01.png

참고: 열은 여러 공백이 아닌 탭으로 구분됩니다.

그리고 sed:

$ sed -E 's/^(s3:.*)\t+(s3:.*)/"\1"\t"\2"/' input.tsv 
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

대신 두 캡처 그룹 사이에 or 를 사용하면 \s+작동하고 동일한 출력이 생성됩니다. 지금 바로[[:blank:]]+\t

sed -E 's/^(s3:.*)[[:blank:]]+(s3:.*)/"\1"\t"\2"/' input.tsv

그리고

sed -E 's/^(s3:.*)\s+(s3:.*)/"\1"\t"\2"/' input.tsv

version은 [[:blank:]]+열 구분 기호로 하나 이상의 공백이나 탭과 일치하고, version은 \s+하나 이상의 공백이나 탭과 일치합니다.어느공백 문자(공백, 탭 등 포함)

그리고 awk:

$ awk -F'\t' '{print "\"" $1 "\"\t\"" $2 "\""}' input.tsv 
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

답변3

탭 문자를 필드 구분 기호로 사용하여 데이터를 CSV 파일로 봅니다.

csvformat -tT -U1 file.tsv >newfile.tsv

이것은 csvformat다음에서 사용됩니다.csvkit탭으로 구분된 입력( -t)을 읽고 탭으로 구분된 출력( )을 생성합니다. 이는 CSV 형식에 필요한지 여부 -T( )에 관계없이 인용됩니다.-U1

파일을 CSV 파일로 처리하고 CSV 파서를 사용하여 인용을 수행하면 필드가 이미 참조된 경우 두 번 참조되지 않는다는 이점이 있습니다.

$ cat file.tsv
"s3://data01/repo01/image live01.png"   s3://Ata01/vol01/image live01.png
s3://data02/repo01/image live01.png     s3://Ata02/vol01/image live01.png
s3://data03/repo01/image live01.png     s3://Ata03/vol01/image live01.png
$ csvformat -tT -U1 file.tsv
"s3://data01/repo01/image live01.png"   "s3://Ata01/vol01/image live01.png"
"s3://data02/repo01/image live01.png"   "s3://Ata02/vol01/image live01.png"
"s3://data03/repo01/image live01.png"   "s3://Ata03/vol01/image live01.png"

분명히 데이터를 직접 읽고 를 호출할 때 큰따옴표를 추가할 수도 있습니다 s3 cp. 그 명령이 어떤 것인지는 모르겠습니다만...

while IFS=$'\t' read -r src dst; do
    s3 cp "\"$src\"" "\"$dst\""
done <file.tsv

답변4

감자 껍질을 벗기는 방법은 여러 가지가 있지만 제 방법은

sed 's;^\(s3://.*\) \(s3://.*\)$;"\1" "\2";' filename_in.tsv > out.tsv

sed입력에 정규식을 적용하고 s3-URL 사이의 공백이 아닌 문자열의 모든 부분을 캡처한 다음 따옴표로 묶는 데 사용됩니다 .

.tsv를 생성하는 도구를 작성하는 사람이 이것으로부터 뭔가를 배울 수 있기를 바랍니다. 예를 들어, 파일 이름에 줄 바꿈이 있으면 복구할 수 없는 오류가 발생할 수도 있습니다. 이는 파일 이름에 완벽하게 적합합니다(S3에서는 확인하지 않았을 수도 있음). ).

"구분 기호에 관계없이" 파일에 파일 이름을 저장하는 것은 좋지 않은 결과를 낳습니다(해당 구분 기호가 0바이트인 경우는 제외). 이는 파일 이름에서 거의 금지된 유일한 바이트입니다. 탈출해야 하거나 더 나은 방법은 긴 파일 이름 목록을 텍스트 파일에 저장하지 말고 대신 간단한 SQLite를 사용하는 것입니다.

관련 정보