![이 정규식 대체가 작동하지 않는 이유는 무엇입니까?](https://linux55.com/image/105153/%EC%9D%B4%20%EC%A0%95%EA%B7%9C%EC%8B%9D%20%EB%8C%80%EC%B2%B4%EA%B0%80%20%EC%9E%91%EB%8F%99%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
다음 형식의 파일이 있습니다.
$ cat myfile
12 42956 Cinema - 3D/Multiplex
7 12560 Status Update
5 184 Movie
텍스트 설명에 큰따옴표를 추가하려고 합니다.
다음 정규식이 작동하지 않는 이유를 이해할 수 없습니다.
$ sed -E 's/\b[0-9]+\b\s*\b[0-9]+\b\s*([^\s]+)/"\1"/g' myfile
내 질문은 동일한 작업을 수행하는 다른 방법이 아니라 이 정규식에 관한 것입니다. 나
답변1
내가 아는 한 은 Perl 정규식이며 \s
. 내부는 "하나와 하나"를 의미합니다. 또한 및 가 동일하더라도 사이에 공백이 있기 때문에 일치하지 않습니다.[[:blank:]]
sed
[ ... ]
\s
\
s
[^\s]+
[^␣]+
Status Update
교체는 모든 항목을 큰따옴표로 묶인 첫 번째 세트로 바꿉니다. 아마도 세 개의 열을 모두 캡처하고 싶을 것입니다. 그렇지 않으면 다음과 같은 결과가 나올 것입니다.오직 마지막 열. 전체 줄을 일치시키려는 경우 ^
및 를 사용하여 시작과 끝 부분에 표현식을 고정하고 $
끝 부분에서 플래그를 제거해야 합니다.g
선택하다:
$ sed -E 's/[[:alpha:]].+/"&"/' myfile
12 42956 "Cinema - 3D/Multiplex "
7 12560 "Status Update "
5 184 "Movie "
데이터가 항상 숫자가 아닌 값으로 시작하는 것처럼 보이므로 마지막 열을 찾습니다. 이 표현식은 첫 번째 알파벳 문자부터 시작하여 줄의 나머지 부분과 일치하고 모든 일치 항목을 큰따옴표 버전의 일치 항목으로 바꿉니다.
질문의 데이터 끝에 공백이 있으며 이는 따옴표에 포함됩니다. 후행 공백을 방지하려면 다음을 수행하십시오.
$ sed -E -e 's/[[:blank:]]*$//' -e 's/[[:alpha:]].+/"&"/' myfile
12 42956 "Cinema - 3D/Multiplex"
7 12560 "Status Update"
5 184 "Movie"
또는,
while read -r a b c; do printf '%d\t%d\t"%s"\n' "$a" "$b" "$c"; done <myfile
12 42956 "Cinema - 3D/Multiplex"
7 12560 "Status Update"
5 184 "Movie"
답변2
sed -E 's/\b([0-9]+\b\s*\b[0-9]+)\b\s*([^\s]+)/\1 "\2"/g' myfile
그러면 텍스트 주위에 큰따옴표가 추가됩니다.
한 그룹에 숫자와 공백을 저장 \1
하고 다른 그룹(\2)에 문자열을 저장하고, sed는 그룹 1(\1), 공백, 큰따옴표, 두 번째 그룹(\2)을 출력합니다. 큰 따옴표.
([0-9, ]*)
모든 숫자와 공백을 하나의 그룹으로 그룹화하고 숫자 뒤의 모든 항목을 다른 그룹으로 그룹화하여 이를 단축할 수 있습니다 (.+)
.
이는 다음을 제공합니다:
sed -E 's/([0-9, ]*)(.+)/\1 "\2"/g' myfile
12 42956 "Cinema - 3D/Multiplex"
7 12560 "Status Update"
5 184 "Movie"
답변3
Mac OSX에서는 지원 sed
하지 않기 때문 입니다 \s
.GNU sed
\s
Mac OSX에서는 ANSI-C 따옴표를 사용해도 \s
작동하지 않습니다.$''
$ echo $'1\t2 3' | sed 's/\s//g'
1 2 3
$ echo $'1\t2 3' | sed $'s/\s//g'
1 2 3
대신에 다음을 사용할 수 있습니다.[[:space:]]
$ echo $'1\t2 3' | sed 's/[[:space:]]//g'
123
또는 를 사용할 수 있지만 탭 문자에 ANSI-C 인용문이 [ \t]
필요합니다 .$''
$ echo $'1\t2 3' | sed $'s/[ \t]//g'
123