使用 sed 和 bash 注释掉一个文件中与另一个文件中的行匹配的文件路径

Comment out file paths in a file matching lines in another file with sed and bash

我有一个包含以下内容的文件 (names.txt):

/bin/pgawk
/bin/zsh
/dev/cua0
/dev/initctl
/root/.Xresources
/root/.esd_auth

...等等。我想逐行读取此文件,并使用 sed 注释掉另一个文件中的匹配项。我有下面的代码,但它什么也没做:

#/bin/bash
while read line
do
        name=$line
        sed -e '/\<$name\>/s/^/#/' config.conf
done < names.txt

输入文件中的行需要在 config.conf 文件中注释掉。如下:

config {
    #/bin/pgawk
    #/bin/zsh
    #/dev/cua0
    #/dev/initctl
    #/root/.Xresources
    #/root/.esd_auth
}

我不想手动执行此操作,因为该文件包含超过 300 个文件路径。有人可以帮我解决这个问题吗?

您需要在 sed 命令周围使用双引号,否则 shell 变量将不会展开。试试这个:

sed "/\<$name\>/s/^/#/" config.conf

但是,我建议您完全跳过 bash for 循环并使用 awk 一次完成所有事情:

awk 'NR==FNR{a[[=11=]];next}{for(i=1;i<=NF;++i)if($i in a)$i="#"$i}1' names.txt config.conf

awk 命令将所有文件名存储为数组中的键a,然后循环遍历配置文件每一行中的每个单词,如果在单词前添加“#”阵列。末尾的 1 表示每行都打印出来。

这里最好不要使用正则表达式匹配,因为你的文件名中的一些字符(比如.)会被正则表达式引擎解释。这种方法做一个简单的字符串匹配,避免了这个问题。