0

In a single directory, I'd like to replace the first line of each file with the file's name. Each file has as the first line "TestRelation." I'd like to replace it with the file's name.

I know I can use perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt to go through all of the files. But how do I dynamically change the "REPLACE_WITH" with the file name?

Faheem Mitha
  • 35,108
Adam_G
  • 413

4 Answers4

1

A shell script with a "here document" will handle this nicely:

#!/bin/bash
for NAME in t?
do
ex -s $NAME << END_EDITS
1s/TestRelation/$NAME/
w!
q
END_EDITS
done

Not knowing what your files are named, I chose "t1", "t2", "t3", etc as file names. You will have to generate file names as appropriate.

The "for" loop gives shell variable NAME the value of a file's name each time through the loop. The bash instance executing the above script calls the ex editor on each file name, and gives it some input lines. The 1s/TestRelation/$NAME/ ex command gets expanded by the bash instance, which substitutes a file's name for the "$NAME" part.

You have to have the token that ends the "here document" (END_EDITS in this case) at the beginning of a line, no white space in front.

1

Try:

perl -i.bak -wpe 's/SEARCH_FOR/$ARGV/g' *.txt

$ARGV contain the name of current file when reading from <>.

Because you using -i switch, you don't have to worry about security implication when running perl with -n or -p switch.

cuonglm
  • 153,898
  • Perfect. Thank you. And for anyone wondering, you can use find . -name "*.bak" -delete to delete all of the .bak files. – Adam_G Feb 08 '15 at 16:09
0

If you just wish to do it in shell, use find command to list files and then basename command to get the file name and use sed to replace the string

for i  in $(find . -type f); do fname=$(basename $i); sed -i "s/TestRelation/${fname}/" $fname; done

Well basename and find is not required and you can just use ls if you are sure of only files in a particular dir you are searching

bluefoggy
  • 662
0

You can try something like this.

for i in `ls *.sh`; do echo "$i">>$i.new; cat $i.new $i >>$i.new;done

What this does it basically list the files and store the filenames. Write those names to a new file and cat it with the original file. You can also move the .new file to the original filename if required. This is not the most elegant option, but it works.

rahul
  • 1,181