Haije Ploeg
Haije Ploeg

Reputation: 172

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

I have a file (names.txt) with the following content:

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

... and so on. I want to read this file line by line, and use sed to comment out matches in another file. I have the code below, but it does nothing:

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

Lines in the input file needs to be commented out in config.conf file. Like follows:

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

I don't want to do this by hand, because the file contains more then 300 file paths. Can someone help me to figure this out?

Upvotes: 3

Views: 528

Answers (1)

Tom Fenech
Tom Fenech

Reputation: 74625

You need to use double quotes around your sed command, otherwise shell variables will not be expanded. Try this:

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

However, I would recommend that you skip the bash for-loop entirely and do the whole thing in one go, using awk:

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

The awk command stores all of the file names as keys in the array a and then loops through every word in each line of the config file, adding a "#" before the word if it is in the array. The 1 at the end means that every line is printed.

It is better not to use regular expression matching here, as some of the characters in your file names (such as .) will be interpreted by the regular expression engine. This approach does a simple string match, which avoids the problem.

Upvotes: 3

Related Questions