当从 echo 输入而不是从文件输入时 sed 可以工作

当从 echo 输入而不是从文件输入时 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  

相关内容