쉼표로 구분된 문자열에서 key=value를 찾아 바꾸는 sed 명령을 작성하려고 합니다.
파일의 문자열 예: KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue
사용된 sed 명령:
sed -r 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/' myFile.txt
키가 존재하는 경우 키와 해당 값을 새 key=value로 바꿉니다. 대부분의 값은 쉼표 ","로 끝나지만 문자열의 마지막 key=value에는 ,가 없다는 점은 예외입니다.
RedHat Linux VM에서 다음과 같은 오류 메시지가 나타납니다.
sed: -e 표현식 #1, char 55: 앞의 정규식이 유효하지 않습니다.
나는 이것이 /g 로 시도한 마지막 "/"라고 생각합니다. 이는 원래 문자열에서 키가 반복되어서는 안 되기 때문에 제외 가능합니다.
답변1
이 sed
유틸리티는 Perl과 유사한 정규식을 지원하지 않습니다.
대신에 다음을 사용할 수 있습니다.
$ sed 's/KEY_2=[^,]*/KEY_2=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
또는
$ sed 's/\(KEY_2\)=[^,]*/\1=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
또는 다음을 사용하여 awk
(정규식을 사용하지 않고 키와 정확한 문자열 일치를 사용하면 KEY_2
및 가 모두 있을 때 혼동을 방지할 수 있습니다 SOME_OTHER_KEY_2
):
$ awk -F, -v OFS=, '{ for (i = 1; i <= NF; ++i)
if (split($i, a, "=") == 2 && a[1] == "KEY_2") {
$i = "KEY_2=new value"
break
} } 1' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
답변2
설명에서 언급했듯이 sed
PCRE 스타일 정규식은 지원되지 않습니다(참조:내 정규 표현식이 X에서는 작동하지만 Y에서는 작동하지 않는 이유는 무엇입니까?). 당신이 perl
사용할 수있는
$ s='KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue'
$ echo "$s" | perl -pe 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
$ echo "$s" | perl -pe 's/SOMEKEY=.*?((?=,)|$)/SOMEKEY=new_value/'
KEY_1=value_1,KEY_2=value_2,SOMEKEY=new_value
정규식을 단순화할 수 있습니다.
$ # -l needed to prevent deleting the newline character for last field
$ echo "$s" | perl -lpe 's/KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
$ # to prevent partial match
$ echo "$s" | perl -lpe 's/(?<![^,])KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue
바라보다perldoc 명령 스위치여기에 사용된 명령줄 옵션에 대한 참고 사항