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

时间:2015-03-25 09:41:18

标签: regex bash awk sed

我有一个文件(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个文件路径。有人能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

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

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

但是,我建议您完全跳过bash for-loop并使用awk一次完成整个过程:

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

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

最好不要在此处使用正则表达式匹配,因为正则表达式引擎会解释文件名中的某些字符(例如.)。这种方法进行简单的字符串匹配,避免了这个问题。