다음과 같은 파일이 있습니다.
1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N
\N을 제외한 모든 \를 #으로 바꾸어 출력이 다음과 같도록 하고 싶습니다.
1,2,subjects,#mat#hs,unix#,#Nato,\N,123,\N
다음과 같은 sed 명령을 작성하려고 합니다.
sed -e 's@\\([^N])@#\1/g' filename
그러나 이는 ex의 시작 부분에 \N이 있는 모든 값에 대해 실패합니다. \Nato
위의 예에서.
내 요구 사항을 충족하는 sed 명령(정규식)을 찾는 데 도움을 줄 수 있는 사람이 있나요?
답변1
나는 별로 능숙하지 않다 sed
. 하지만 이는 perl
정규식 둘러보기를 사용하여 쉽게 수행할 수 있습니다.
perl -pe 's/\\(?!N\b)/#/g' your_file_here
그러면 수정된 파일이 표준 출력으로 인쇄됩니다. 교체하려면 다음을 수행할 수 있습니다.
perl -pi -e 's/\\(?!N\b)/#/g' your_file_here
기본적으로 이는 따르지 않는 백슬래시 N\b
(단어 경계에 있는 문자 N)를 로 대체합니다 #
.
편집하다
항목이 쉼표로 구분되어 있다고 확신하는 경우 다음을 수행하여 \N
단어 끝 대소문자를 무시할 수 있습니다( SOLEM\N
제공한 예와 같이).
perl -pe ' s/\\/#/g; s/(\A|,)\s*#N\s*(\Z|,)/$1\\N$2/g;' your_file_here
백슬래시를 해시 토큰으로 바꾼 다음 #N
두 개의 쉼표 사이, 문자열의 시작과 쉼표 사이, 또는 쉼표와 문자열의 끝 사이에서 찾은 내용을 찾습니다.
답변2
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N' \
| sed -r -e 's@\\([^N]|N[^,])@#\1@g'
1,2,subjects,#mat#hs,unix#,#Nato,\N,123,\N
편집하다단어 대소문자의 일부인 \N의 경우: (주석 참조)
$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
| sed -r -e 's@,\\N$@,:SINGLE_N_PLACEHOLDER:@g' \
-e 's@^\\N,@:SINGLE_N_PLACEHOLDER:,@g' \
-e 's@,\\N,@,:SINGLE_N_PLACEHOLDER:,@g' \
-e 's@\\@#@g' \
-e 's@:SINGLE_N_PLACEHOLDER:@\\N@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N
이것은 추악하고 신뢰할 수 없습니다(자리 표시자 문자열은 고유해야 하며 패턴이 텍스트에 나타나면 작동이 중지됩니다). 그러나 sed가 주장을 지원하는 방식으로 PCRE/Perl을 사용하도록 하는 작업 방법을 찾지 못했습니다.
다음과 같이 단축할 수 있습니다.
$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
| sed -r -e 's@\\@#@g' \
-e 's@(,|^)#N(,|$)@\1\\N\2@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N
그러나 이 경우에는 string이 #N
문자열에 나타나서는 안 되는 자리 표시자입니다.
답변3
sed -e 's@\\\([^N]\|\(N[a-zA-Z]\|$\)\)@#\1@g' your_file_here
설명: \
다음을 모두 교체하세요.
- 아무것도 없어요
N
, - 또는
N
그 뒤에 임의의 문자가 옵니다[a-zA-Z]
(필요한 경우 확장 가능) - 줄 끝
#
및 나머지 일치 패턴 과 함께 .
답변4
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N' |
sed -r -e 's/\\N/XELI/g' |
sed -e 's/\\/#/g' |
sed -e 's/XELI/\\N/g'
1,2,subjects,#mat#hs,unix#,\Nato,\N,123,\N
분할하는 것이 더 읽기 쉽다고 생각합니다.
- \N을 발생하지 않는 일부 문자로 바꾸십시오.
- 그런 다음 /를 #으로 바꾸십시오.
- /N을 다시 교체하세요.