我一直试图创建一个sed脚本,该脚本读取电话号码列表,并且仅打印与以下方案匹配的电话号码:
我是一个绝对的初学者,但是我尝试编写一个 sed 脚本,该脚本将使用-n -r
标志(其内容如下)为我打印此脚本:< / p>
/\+1\(212\)[0-9]{3}-[0-9]{4}/p
/1\(212\)[0-9]{3}-[0-9]{4}/p
如果我直接在sed中运行它,则可以正常工作(即sed -n -r '/\+1\(212\)[0-9]{3}-[0-9]{4}/p' sample.txt
按预期打印匹配的行。这在我编写的sed脚本中不起作用,而是sed表示:
sed:-e表达式#1,字符2:命令后的多余字符
我找不到一个好的解决方案,这个错误似乎有很多原因,而且我发现的所有答案在这里都不容易。
编辑:我用sed -n -r script.sed sample.txt
答案 0 :(得分:2)
sed
无法自动确定您希望参数是脚本文件还是脚本字符串。
要从文件运行sed脚本,必须使用-f
:
$ echo 's/hello/goodbye/g' > demo.sed
$ echo "hello world" | sed -f demo.sed
goodbye world
如果您忽略-f
,sed
将尝试以命令的形式运行文件名,而d
elete命令不愿意在其后加上emo.sed
:
$ echo "hello world" | sed demo.sed
sed: -e expression #1, char 2: extra characters after command
答案 1 :(得分:0)
在各种unix工具中,有两个使用BRE作为其默认的regex方言。这两个工具是sed
和grep
。
在大多数操作系统中,您可以使用egrep
或grep -E
来告诉该工具使用ERE作为其方言。数量较少(但仍然很重要)的sed
实现将接受-E
选项来使用ERE。
但是,在BRE模式下,您仍然可以使用方括号创建原子。并且您可以通过转义括号来做到这一点。这就是为什么您的初始表达式失败的原因-括号在BRE中默认不是特殊的,但是您要在字符前面加上反斜杠来使它们成为特殊字符。
要记住的另一件事是,如果要sed
从命令行参数执行脚本,则应使用-e
选项。
所以:
$ cat ph.txt
+1(212)xxx-xxxx
1(212)xxx-xxxx
212-xxx-xxxx
$ grep '^+\{0,1\}1([0-9]\{3\})' ph.txt
+1(212)xxx-xxxx
1(212)xxx-xxxx
$ egrep '^[+]?1\([0-9]{3}\)' ph.txt
+1(212)xxx-xxxx
1(212)xxx-xxxx
$ sed -n -e '/^+\{0,1\}1([0-9]\{3\})/p' ph.txt
+1(212)xxx-xxxx
1(212)xxx-xxxx
$ sed -E -n -e '/^[+]?1\([0-9]{3}\)/p' ph.txt
+1(212)xxx-xxxx
1(212)xxx-xxxx
根据您的操作系统,您可能可以从man re_format
获取有关其工作方式的完整列表。