bash 正确转义 sed 字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2075651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:33:41  来源:igfitidea点击:

Escaping sed strings correctly

bashsedescaping

提问by Chris Lieb

I have a regex and replacement pattern that have both been tested in Notepad++ on my input data and work correctly. When I put them into a sed expression, however, nothing gets matched.

我有一个正则表达式和替换模式,它们都在 Notepad++ 中对我的输入数据进行了测试并且正常工作。然而,当我将它们放入 sed 表达式时,没有任何匹配。

Here is the sed command:

这是 sed 命令:

 # SEARCH = ([a-zA-Z0-9.]+) [0-9] (.*)
 # REPLACE =  ()

 sed -e 's/\([a-zA-Z0-9.]+\) [0-9] \(.*\)/ \(\)/g'

Here is a sampling of the data:

以下是数据的样本:

jdoe 1 Doe, John
jad 1 Doe, Jane
smith 2 Smith, Jon

and the desired output:

和所需的输出:

Doe, John  (jdoe)
Doe, Jane  (jad)
Smith, Jon (smith)

I have tried removing and adding escapes to different characters in the sed expression, but either get nothing matched or something along the lines of:

我已经尝试在 sed 表达式中删除和添加不同字符的转义符,但要么没有匹配到任何内容,要么类似于:

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

How can I get this escaped correctly?

我怎样才能正确地转义这个?

回答by Mark Byers

I usually find it easier to use the -r switch as this means that escaping is similar to that of most other languages:

我通常发现使用 -r 开关更容易,因为这意味着转义类似于大多数其他语言:

sed -r 's/([a-zA-Z0-9.]+) [0-9] (.*)/ ()/g' file1.txt

回答by D.Shawley

A few warnings and additions to what everyone else has already said:

对其他人已经说过的一些警告和补充:

  1. The -roption is a GNU extension to enable extended regular expressions. BSD derived sed's use -Einstead.
  2. Sedand Grepuse Basic Regular Expressions
  3. Awkuses Extended Regular Expressions
  4. You should become comfortable with the POSIX specificationssuch as IEEE Std 1003.1if you want to write portable scripts, makefiles, etc.
  1. -r选项是一个 GNU 扩展,用于启用扩展的正则表达式。BSD 派生 sed 的使用-E代替。
  2. SedGrep使用基本的正则表达式
  3. awk使用扩展正则表达式
  4. 如果您想编写可移植的脚本、makefile 等,您应该熟悉POSIX 规范,例如IEEE Std 1003.1

I would recommend rewriting the expression as

我建议将表达式重写为

's/\([a-zA-Z0-9.]\{1,\}\) [0-9] \(.*\)/ ()/g'

which should do exactly what you want in any POSIX compliant sed. If you do indeed care about such things, consider defining the POSIXLY_CORRECTenvironment variable.

在任何符合 POSIX 的sed. 如果您确实关心这些事情,请考虑定义POSIXLY_CORRECT环境变量。

回答by Paused until further notice.

The plus sign needs to be escaped when not using the -rswitch.

不使用-r开关时,加号需要转义。

回答by fwaechter

Using awk is much simpler...:

使用 awk 要简单得多...:

cat test.txt | awk '{ print  " "  " " "("")" }'

Output:

输出:

Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)

See man awk 1

参见 man awk 1

回答by ghostdog74

$ sed -e 's/\([a-zA-Z0-9.].*\) [0-9] \(.*\)/ \(\)/g' file
Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)