当从 echo 输入而不是从文件输入时 sed 有效

Jim*_*Jim 1 linux osx shell sed regular-expression

以下删除电子邮件地址字符串的周围引号:

$ echo  "john.doe@gmail.com" | sed 's/"([^"]*)"/\0/g'  
john.doe@gmail.com  
Run Code Online (Sandbox Code Playgroud)

但如果:

$ cat ~/Desktop/emails.txt 
"john.doe@gmail.com"  
$ sed 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt    
"john.doe@gmail.com"   
$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt
$ cat ~/Desktop/emails.txt 
"john.doe@gmail.com"  
Run Code Online (Sandbox Code Playgroud)

尝试使用包含相同字符串的文件应用完全相同的 sed 正则表达式替换不起作用。
我究竟做错了什么?

and*_*coz 9

很抱歉,您的echo示例不起作用。它似乎有效,因为双引号 ( ") 被解释bash并从未传递给sed.

请注意以下两个示例之间的区别:

$ echo "john.doe@gmail.com" 
john.doe@gmail.com
$ echo "\"john.doe@gmail.com\"" 
"john.doe@gmail.com"
Run Code Online (Sandbox Code Playgroud)

您的echo命令没有提供"tosed所以它似乎可以工作,因为"输入字符串中没有要删除的内容。

如果您尝试正确转义",该echo示例将无法作为file示例工作:

$ echo  "\"john.doe@gmail.com\"" | sed 's/"([^"]*)"/\0/g'  
"john.doe@gmail.com"
Run Code Online (Sandbox Code Playgroud)

你的sed命令有两个错误:

  1. 您正在使用扩展的正则表达式语法。只有你有gnused才能使用它。不同之处在于他们使用括号的方式。
  2. 您必须从1.

所以正确的命令是:

echo  "\"john.doe@gmail.com\"" | sed 's/"\([^"]*\)"/\1/g' 
Run Code Online (Sandbox Code Playgroud)

或者,如果您sed支持扩展正则表达式:

echo "\"john.doe@gmail.com\"" | sed -E 's/"([^"]*)"/\1/g'
Run Code Online (Sandbox Code Playgroud)