sed에서 여러 번 재사용하기 위해 복잡한 정규식을 어떻게 저장합니까?


12

를 사용할 sed때 파일에서 두 번 일치 해야하는 다소 복잡하고 복잡한 정규 표현식을 종종 만듭니다. 이 정규식을 저장하고 두 번 참조하는 방법이 있습니까?

아마도 이런 모양일까요?

sed ' complicated_regex=/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/
s/complicated_regex:complicated_regex/simple-output/
' my_file

업데이트 : 대답은 bash 변수를 사용하는 솔루션을 제시했습니다. 작동하지 않습니다. 주어진 test.txt.

#test.txt
foo bar
bar foo

그리고 대본

#!/bin/bash

VALUE='foo \([a-z]\+\)'

sed 's/"${VALUE}"/foo happy \1/' test.txt

이것은 출력을 생성해야합니다

foo happy bar
bar foo

그러나 대신 오류가 발생합니다.

sed: -e expression #1, char 24: invalid reference \1 on `s' command's RHS

펄을 사용하는 경우 표현 내에서 표현의 이전 부분을 참조 할 수 있습니다 :perl -pe 's/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+:\1$/simple_output/' my_file
글렌 잭맨

1
sed에 너무 복잡한 것을 발견하면 망설이지 말고 awk 또는 perl을 찾으십시오.
Gilles 'SO- 악의를 멈춰라'

2
@Cory : 구문이 맞다면 예제가 잘 작동합니다. 당신은 "$ 변수"아직 ... 그것이 있어야 예상 쉘 확장에서 가죽을 '작은 따옴표'에 동봉sed 's/'"${VALUE}"'/foo happy \1/' test.txt
Peter.O

답변:


7

쉘 변수를 사용할 수 있습니다 :

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

의 의미에 대해 잘 모르겠지만 $i작은 따옴표 외부에 넣어야 할 수도 있습니다.

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'

물론 이것은 sed명령이 셸에서 호출 된 경우에만 작동 하지만 거의 모든 프로그래밍 언어와 유사한 솔루션이 있습니다. (그리고 나는 안에 변수를 사용할 수 있다고 생각하지 않는다 sed.)
Stéphane Gimenez

으르렁 이것을 시도하면 역 참조가 깨지는 것 같습니다. s/$complicated_regex/\1/잘못된 참조임을 나타내는 오류를 제공합니다.
코리 클라인

아아, 아마도 내 잘못은 변수 대체를 zsh하는 데 익숙합니다. 업데이트 된 답변을 참조하십시오.
Stéphane Gimenez

변수에서 앵커를 제거하고 sed 스크립트에 배치해야합니다.sed "s/^${complicated_regex}:${complicated_regex}\$/simple-output/" my_file
glenn jackman

어이! 예, 나는 유효한 정규식 연결 :-) 제공 한 것을 확인하는 것을 잊었다
스테판 히메네스

0

쉘 변수 값을 드롭하고 스크립트 sed의 나머지 부분에서 백 슬래시 이스케이프가 어떻게 변경되어야하는지 걱정하지 않는 가장 쉬운 방법 은 변수를 제외한sed 모든 것을 작은 따옴표로 묶고 큰 따옴표로 묶는 것입니다.

다음 코드 예제는 모두 가정합니다. VALUE='foo \([a-z]\+\)'

변수 가 확장되지 않아 다음과 같은 깨진 코드가 실패합니다 VALUE.

sed 's/"${VALUE}"/foo happy \1/' test.txt

다음 깨진 코드 \1는 쉘 에서 백 슬래시를 먹기 때문에 실패합니다 (작은 따옴표가 아닌 큰 따옴표로 인해) sed.

sed "s/${VALUE}/foo happy \1/" test.txt

다음 코드는 예상대로 작동합니다.

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

다음 코드도 작동합니다.

sed "s/${VALUE}/foo happy \\1/" test.txt

다음도 마찬가지입니다.

sed s/"${VALUE}"/foo\ happy\ \\1/ test.txt

그러나 왜 복잡 해지는가? sed스크립트를 둘러싼 작은 따옴표는 특히 스크립트를 배우지 않는 비 구독자가 코드를 읽는 경우 모든 것을 훨씬 명확하게 만듭니다. 내가 선호하는 방법은 변수 확장을 위해 작은 따옴표를 큰 따옴표로 바꾸고 작은 따옴표로 바로 이동하는 것입니다.

sed 's/'"${VALUE}"'/foo happy \1/' test.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.