微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sed不能在bash脚本中工作

我已经阅读了关于这个主题的所有类似问题,但是没有find与我正在经历的匹配问题。 我很抱歉,如果这已被回答。

在我写的bash脚本里面,有一个非常简单的sed命令,它似乎没有工作。 没有错误,从命令行运行命令完美。

在set -x的输出中,我可以看到sed命令执行完美。

GNU bash,版本4.3.11(1)-release(x86_64-pc-linux-gnu)

将来自bash脚本的环境variables分配给来自Python的当前会话

用于重命名和重新排列文件的脚本shell

RegEx中的bash脚本(for循环)

如何运行我的循环Bash脚本作为服务?

如果目标文件不存在,如何退出shell脚本

Bash脚本:(为了更容易理解而调低)

#!/bin/bash -x # This script has the exact same sed command as used on cli contact='"[email protected]"' sed -i "/$contact/d" /home/tim/Desktop/file.txt exit

shell输出

tim@ubuntu:~/Desktop$ cat file.txt t,b,[email protected] tim@ubuntu:~/Desktop$ ./test.sh + contact='"[email protected]"' + sed -i '/"[email protected]"/d' /home/tim/Desktop/file.txt + exit tim@ubuntu:~/Desktop$ cat file.txt t,[email protected] tim@ubuntu:~/Desktop$ sed -i "/"[email protected]"/d" /home/tim/Desktop/file.txt tim@ubuntu:~/Desktop$ cat file.txt tim@ubuntu:~/Desktop$

我想我错过了一些非常明显的东西,但是我正在盯着它,希望答案跳下屏幕,拍我的脸。 请帮忙 :-)

蒂姆

无法附加到运行Docker容器的bash

PHP脚本执行一个Bash脚本

符号链接性能打击?

将ls命令的结果保存在本地机器上的远程sftp服务器上

错误:ld.so:对象LD_PRELOAD无法预加载:忽略

$contact脚本变量中的邮件地址周围有双引号,这些变量在命令行调用中缺少:

# case 1 - works # only the sed pattern delimiters are enclosed in quotes and these quotes will be stripped by the shell. sed -i "/"[email protected]"/d" ./file.txt; cat file.txt # case 2 - fails # escaping with turns dquotes #2,3 from shell-level delimiters to char literals w/o special semantics. sed -i "/"[email protected]"/d" ./file.txt; cat file.txt # case 3 - fails # Single quotes enclose the complete sed pattern spec which comprises double quotes enclosing the mail address sed -i '/"[email protected]"/d' ./file.txt; cat file.txt # case 4 - works sed -i "/[email protected]/d" ./file.txt; cat file.txt # case 5 - works sed -i '/[email protected]/d' ./file.txt; cat file.txt

这将解释脚本与cli调用的不同行为。

OP指出他需要真实脚本中的双引号。 可能是这样,但是,如果这些双引号不存在于文件中,则不会有匹配。

解决办法是使用sed预处理文件(如有必要,在一个副本上工作):

sed -i 's/,/","/g; s/^/"/; s/$/"/' ./file.txt

此命令假定每行中不包含包含双引号的项目的逗号分隔列表。 它将用双引号包裹每个项目,以便它们将匹配原始脚本的$contact变量中的搜索模式。

替代 (改编自这个SO回答 [我不是作者])

另一种方法是改变脚本的相关部分,从$contact派生第二个变量:

contact='"[email protected]"' c2=$(echo $contact | tr -d '"') sed -i "/$c2/d" /home/tim/Desktop/file.txt

这仅仅是collapsar的答案已经解决了问题的补充。

当我们在bash脚本中使用sed时,bash脚本充当sed的包装。 这有两个目的

sed命令可以像在bash之外执行一样执行。

bash脚本包装器使用环境变量帮助sed与外部世界进行通信。

例如,假设文件testfile包含两行

[email protected] [email protected]

现在如果我想编写一个bash脚本来帮助sed替换包含[email protected]的行,我的脚本sedscript会是这样的:

#!/bin/bash contact='[email protected]' sed -i "/$contact/d" $1

现在我将执行如下的脚本

./sedscript testfile

删除所有包含[email protected]的行。

事实上,你可以用实际的文件名替换$ 1。 但是,正如前面的答案中提到的,重要的一点是,只要我们在sed命令中使用bash变量,就总是用双引号括起来。 只有在bash将其传递给sed之前,bash才会用相应的字符串替换该变量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐