![Unix 명령에서 이스케이프 구분 기호를 피하는 방법은 무엇입니까?](https://linux55.com/image/36363/Unix%20%EB%AA%85%EB%A0%B9%EC%97%90%EC%84%9C%20%EC%9D%B4%EC%8A%A4%EC%BC%80%EC%9D%B4%ED%94%84%20%EA%B5%AC%EB%B6%84%20%EA%B8%B0%ED%98%B8%EB%A5%BC%20%ED%94%BC%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
물결표(~)로 구분된 필드의 합계를 계산해야 합니다. 내가 겪고 있는 문제는 내 데이터에도 구분 기호 이스케이프가 있다는 것입니다.
예
1~CEO~ashok\~kumar~1000
위의 세 번째 필드에서 볼 수 있듯이 피하고 싶은 구분 기호를 이스케이프 처리했습니다. 다음 명령을 실행하고 있지만 문제가 처리되지 않습니다.
$ cat test.out|awk -F'~' 'BEGIN {sum=0} {sum+=$4} END{print sum}'
test.out
데이터가 다음과 같다고 가정합니다 .
1~CEO~ashok\~kumar~1000
2~CFO~Ranjan~2000
3~CEO~kumar~1000
따라서 내 출력은 4000이 되어야 합니다. 하지만 현재 내 명령으로는 3000밖에 얻지 못합니다!
답변1
처리하기 전에 이스케이프 구분 기호를 다른 것으로 변경하십시오 awk
. 이는 다음을 통해 수행할 수 있습니다 sed
.
$ cat test.out| sed 's/\\~/=/g' | \
awk -F'~' 'BEGIN {sum=0} {sum+=$4} END{print sum}'
4000
그리고 흔히 그렇듯이 다음을 수행할 필요도 없습니다 cat
.
$ sed 's/\\~/=/g' test.out | awk -F'~' 'BEGIN {sum=0} {sum+=$4} END{print sum}'
답변2
사용되지 않는 대안은 다음과 같습니다 awk
.
$ sed 's/\\~/=/g' test.out | cut -d"~" -f4 | paste -sd+ | bc
4000
위의 코드는 세 번째 열에서 이스케이프된 물결표를 sed
바꿉니다 . \~
그런 다음 cut
를 사용하여 숫자의 네 번째 열을 선택하고 더하기 기호( )로 구분되도록 다시 구성 할 수 있습니다 +
.
$ sed 's/\\~/=/g' test.out | cut -d"~" -f4 | paste -sd+
1000+2000+1000
그런 다음 이 문자열은 이진 계산기에 입력되어 bc
합계를 냅니다.
답변3
이스케이프를 처리하기 위한 일반적인 접근 방식은 perl
역추적 연산자 없이 PCRE와 교대 정규식 연산자를 결합하는 것입니다. GNU는 다음과 같습니다 grep
.
grep -Po '(?>(?:\\.|.)*?~){3}\K(?:\\.|[^~])*' << \EOF
1~CEO~ashok\~kumar~1000
2~CFO~Ranjan~2000
3~CEO~kumar~1000
4~field2~field3\\~10000~field5-note-the-escaped-backslash-not-tilde
5~a\~b\~c\~no-4th-field-here
EOF
이것은 만든다:
1000
2000
1000
10000
(평상시 에 추가할 수 있습니다 awk '{s+=$0};END{print s}'
).
GNU를 사용하면 sed
다음과 같은 작업도 수행할 수 있습니다.
sed -rn 's/((\\.|[^\~])*~){3}((\\.|[^~])*).*/\3/p'
GNU를 사용하면 필드를 이스케이프 문자나 물결표가 아닌 문자 또는 백슬래시 문자의 시퀀스로 정의 awk
할 수 있습니다 .FPAT
awk -v FPAT='(\\\\.|[^\\\\~])*' '{print $4}'
답변4
이는 awk에서 약간 다루기 어렵습니다(구분 기호를 변경하기 위해 소스 코드를 전처리할 수 있지만 입력에 나타날 수 없는 다른 문자나 문자 시퀀스를 알아야 하는 경우는 제외). 당신이 할 수 있는 한 가지는 전체 줄을 읽은 다음 줄 바꿈 문자를 구분 기호로 사용하도록 줄을 수정하는 것입니다(줄 바꿈은 줄에 나타날 수 없는 유일한 것입니다).
awk 'BEGIN {FS="\n"}
{
gsub("~", "\n");
gsub("\\\n", "~");
gsub("\\\\", "\\");
$0 = $0;
print $4;
}'