sed는 입력이 파일 대신 에코에서 올 때 작동합니다.

sed는 입력이 파일 대신 에코에서 올 때 작동합니다.

다음은 이메일 주소 문자열 주위의 따옴표를 제거합니다.

$ echo  "[email protected]" | sed 's/"([^"]*)"/\0/g'  
[email protected]  

하지만 만약에:

$ cat ~/Desktop/emails.txt 
"[email protected]"  
$ sed 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt    
"[email protected]"   
$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt
$ cat ~/Desktop/emails.txt 
"[email protected]"  

동일한 문자열이 포함된 파일을 사용하여 정확히 동일한 sed 정규식 대체를 적용하려고 하면 작동하지 않습니다.
내가 뭘 잘못했나요?

답변1

죄송합니다. 귀하의 echo예가 작동하지 않습니다. 큰따옴표( ")는 해석되고 bash전달되지 않기 때문에 작동하는 것 같습니다 sed.

다음 두 예제의 차이점을 확인하세요.

$ echo "[email protected]" 
[email protected]
$ echo "\"[email protected]\"" 
"[email protected]"

귀하의 echo명령은 제공되지 않으므로 제거할 입력 문자열에 아무것도 없기 "때문에 작동하는 것 같습니다 .sed"

"이 예제는 올바르게 이스케이프하려고 하면 echo작동하지 않습니다 file.

$ echo  "\"[email protected]\"" | sed 's/"([^"]*)"/\0/g'  
"[email protected]"

명령 sed에 두 가지 오류가 있습니다 .

  1. 확장 정규식 구문을 사용하고 있습니다. sed가 있는 경우에만 사용할 수 있습니다 gnu. 차이점은 괄호를 사용하는 방식에 있습니다.
  2. 로 시작하는 역참조를 계산해야 합니다 1.

따라서 올바른 명령은 다음과 같습니다.

echo  "\"[email protected]\"" | sed 's/"\([^"]*\)"/\1/g' 

또는 sed확장 정규식을 지원하는 경우:

echo "\"[email protected]\"" | sed -E 's/"([^"]*)"/\1/g'

답변2

gv@debian:$ cat a.txt
"[email protected]"

gv@debian:$ sed 's#"##g' a.txt #remove all quotes
[email protected]

gv@debian:$ cat a.txt |tr -d '"' #remove all quotes
[email protected]

gv@debian:$ sed 's#^"##g; s#"$##g' a.txt #remove first and last quote 
[email protected]

gv@debian:$ a="\"[email protected]\"";echo -e "$a" "\n" "${a: 1:-1}" #remove first and last char
"[email protected]" 
 [email protected]

답변3

@andcoz가 언급했듯이 이것은

$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt

parentheses이스케이프 처리하고 에서 backreference로 변경 해야 합니다 .\0\1

수정 후 함수 sed명령은 다음과 같습니다.

$ sed -i '' 's/"\([^"]*\)"/\1/g' ~/Desktop/emails.txt  

관련 정보