在Linux中使用sed/awk替换字符串

4
我想要替换这个。
#!/usr/bin/env bash

使用这个

   #!/bin/bash

我已经尝试了两种方法
方法1
original_str="#!/usr/bin/env bash"
replace_str="#!/bin/bash"

sed s~${original_str}~${replace_str}~ filename

方法二
line=`grep -n "/usr/bin" filename`
awk NR==${line} {sub("#!/usr/bin/env bash"," #!/bin/bash")}

但它们两个都没有工作。


4
“不工作”从来都不是一个足够好的问题描述。请更具体地说明问题(解释具体发生了什么并显示错误信息)。 - hoijui
3个回答

24

如果在BASH中双引号内使用 !,历史扩展将会发生,为避免此类情况,您可以:

original_str='/usr/bin/env bash'
replace_str='/bin/bash'

sed "s~$original_str~$replace_str~" file
#!/bin/bash

1
谢谢,这在 drone.io 中显然也是必需的。 - Orphans

6

使用转义字符:

    $ cat z.sh
    #!/usr/bin/env bash

    $ sed -i "s/\/usr\/bin\/env bash/\/bin\/bash/g" z.sh

    $ cat z.sh
    #!/bin/bash

4

在终端中尝试以下命令:

echo "#!/usr/bin/env bash" | sed 's:#!/usr/bin/env bash:#!/bin/bash:g'

在这种情况下,我使用:作为分隔符,因为sed无法区分不同的斜杠,无法确定哪个是分隔符,哪个是文本的一部分。此外,这样看起来非常清晰。 酷的是,您可以使用任何符号作为分隔符。例如,分号;或管道符号|。 通过使用转义字符 \,我认为代码会变得太乱,并且不易读,因为您必须在命令中的每个正斜杠之前都要加上它。

上面的命令将只打印替换后的行,但如果要修改文件,则需要指定输入和输出文件,如下所示:

sed 's:#!/usr/bin/env bash:#!/bin/bash:g' <inputfile >outputfile-new

请记住,如果输入文件和输出文件具有相同的名称,则要添加-new,否则您的原始文件将被完全清除:这在过去发生过,这并不是最好的事情。例如:

<test.txt >test-new.txt


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接