쉘 스크립트에서 기호를 어떻게 이스케이프합니까?

쉘 스크립트에서 기호를 어떻게 이스케이프합니까?

쉘 스크립트를 사용하여 다른 파일에 텍스트를 쓰고 싶지만 echo데이터가 의도한 대로 정확한 형식으로 기록되지 않습니다.

echo paste B01_reprojected_subset_comma_updated.csv  B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'>allbands.csv >> jobstext.sh

그런데 jobstext.sh에서 이런 문자가 왔어요

paste B01_reprojected_subset_comma_updated.csv B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv,,,,,,,,,,,,,,

특수 기호를 이스케이프 처리하려고 했지만 여전히 데이터 형식이 정확하지 않습니다.

누구든지 내가 이 일을 하도록 도와줄 수 있나요?

paste B01_reprojected_subset_comma_updated.csv B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'>allbands1.csv

답변1

쉘이 텍스트(예: $and >또는 같은 특수 문자 포함)에 닿지 않도록 하려면 *모든 것을 작은따옴표로 묶으십시오. 문자열에 작은따옴표를 포함하려면 인용된 문자열을 중단하고 백슬래시로 이스케이프된 작은따옴표를 추가해야 합니다 'here comes the embedded '\''quote'.

echo 'paste B01_reprojected_subset_comma_updated.csv  B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '\''{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'\''>allbands.csv' >> jobstext.sh

답변2

printf인쇄를 분할하고 형식 문자열을 사용하여 출력을 정렬하면 더 쉽습니다 . 먼저, 중괄호 확장을 활용하는 붙여넣기 명령:

printf "%s " paste B{01..12}_reprojected_subset_comma_updated.csv >> jobstext.sh

그런 다음 OFS를 사용하여 단순화된 awk 명령:

printf "| %s '%s' %s %s '%s' > %s\n" awk -F',|\t' -v OFS=, '{print $1, $2, $3, $6, $9, $12, $15, $18, $21, $24, $27, $30, $33, $36, $39}' allbands1.csv >> jobstext.sh

%q를 사용 하여 에 사용되는 형식 문자열을 단순화 할 수도 있습니다 printf.

답변3

파일 샘플이나 수행하려는 작업에 대한 명확한 설명 또는 원하는 출력 파일 형식이 없으면 이는 단순한 추측일 뿐입니다. 아마도 jobstext.sh 파일에 명령줄(paste stuff|awk action)을 추가하고 싶을 수도 있습니다. 중첩된 인용 문제를 피하기 위해 편집기를 사용하는 것이 더 나을 것입니다...

그러나 귀하의 질문은 특수 문자를 이스케이프 처리하는 것에 대해 묻습니다. 한 가지 옵션은 큰 따옴표 안에 작은 따옴표를 캡슐화하는 것입니다. 긴 파일 이름을 B01 등으로 줄이면 아래와 같습니다.

echo 'paste B01 B02 B03 B04 B05 B06 B07 B08 B8A B09 B10 B11 B12 |
awk -F",||\t" '"'"'{print "$1","$2","$3","$6","$9","$12","$15","$18","$21",
"$24","$27","$30","$33","$36","$39}'"'"' >allbands.csv' >> jobstext.sh

첫 번째 작은따옴표는 붙여넣기 명령, 파일 이름, 파이프, awk 및 F 옵션을 포함하는 문자열을 시작합니다. 그런 다음 시퀀스의 첫 번째 작은따옴표가 '"'"'문자열을 닫고, 다음 3개 문자는 작은따옴표의 또 다른 문자열을 정의하며, 마지막 문자는 세 번째 문자열(중괄호 안에 awk 작업 포함)을 시작하는 작은따옴표입니다. 비슷한 5개의 따옴표 시퀀스가 ​​해당 문자열을 닫고 다른 작은따옴표를 삽입한 다음 다섯 번째 문자열을 시작합니다(출력을 allbands.csv로 리디렉션하는 것으로 구성됨). 마지막으로 해당 문자열이 닫혀(줄의 마지막 따옴표 포함) 5개 문자열이 모두 연결되어 jobstext.sh에 추가됩니다.

이는 번거롭지만 하나의 명령줄에서 두 가지 수준의 작은따옴표를 사용하려고 하면 발생합니다. awk 문이 셸에서 해석되는 것을 방지하려면 작은따옴표가 필요합니다.

개선 사항은 1/ 확장할 수 있는 파일 이름을 사용하는 것입니다 *(그러나 "B8A"는 단순한 파일 이름 확장을 방해하는 불일치를 발생시킵니다). 2/ jobstext.sh에서 명령을 편집하여 명령을 단순화합니다. @muru의 답변에 있는 제안은 통합할 가치가 있습니다(단, "B8A" 파일은 주의하세요!)

관련 정보