I have a large number of files which contain text. All files contain the word "replace" (no quotes). I would like to replace that word with the name of the file.

Example, filename is: On Time.txt

Replace the word "replace" (no quotes) with "On Time" (no quotes).

  • Are all these files in the same directory ? Also, do you want to substitute "replace" only if it's a "word" or anywhere this string may occur (e.g. if it's part of the word "irreplaceable") ? – don_crissti Mar 15 '16 at 22:26
  • Good points I should have included. Yes, all files are in the same directory. And the file contents are minimal: "replace" is meant to be replaced with something; "irreplaceable" does not occur in any of the files. – Phydeaux Mar 15 '16 at 22:42
for filename in "On time.txt" ; do
  replacement=$(echo $filename | sed -e 's,^.*/,,' -e 's,\.[^\.]*$,,')
  [ -f "$filename" ] && sed -i "s,replace,$replacement," "$filename"

To do all files in your directory, replace "On time.txt" with * like this:

for filename in * ; do

Note that here filenames must not contain commas (you can choose the character so that it does not appear in your filenames).

| improve this answer | |
  • basename --suffix is not recognized in my distro. – marc Mar 15 '16 at 21:56
  • Sorry, I'm on Ubuntu 15.10 and I didn't check. I replaced it with another sed, so that it should work even if you're not using bash (but @mmmint 's % is good too). – Law29 Mar 15 '16 at 22:00
  • The sed will remove anything following a period in the file name. One could limit it to only three-character extensions if necessary (this will fail on "hidden" files like .bashrc for example) – Law29 Mar 15 '16 at 22:03
  • This one was the winner for me. Thanks so much! – Phydeaux Mar 15 '16 at 22:45
  • @Phydeaux if this was the best answer for you, you should accept it by clicking on the large tick to the left of the answer. – cas Mar 15 '16 at 23:38

I would use sed for that:

for f in *.txt

    # filename without path (on_time.txt)
    filename=$(basename "$fullfile")

    # remove extension of filename (on_time)

    # replace all occurrences of "replace" with "on_time" in file
    sed -i -e "s/replace/$filename_woext/g" $filename

| improve this answer | |
  • sed -i -e 's/replace/"$filename_woext"/g' $filename will not expand $filename_woext, you need sed -i -e "s/replace/$filename_woext/g" $filename. – Law29 Mar 15 '16 at 22:08
  • Wow, never thought I would have multiple answers within minutes! Both of these answers worked a treat, however I chose to adopt the one proposed by Law29 since the one by mmmint didn't seem to like filenames with spaces, though I'm sure someone sharper than I could tweek that. Thank you Both very much! – Phydeaux Mar 15 '16 at 22:35
  • if you're using basename, you can just do filename=$(basename "$fullfile" .txt) to remove the path AND the extension at the same time. Also, "$fullfile" is redundant, you already have the full filename in $f, so why assign it to another variable? Simpler version:. for f in *.txt ; do filename=$(basename "$f" .txt) ; sed -i -e "s/replace/$filename/g" $f ; done or even for f in *.txt ; do sed -i -e 's/replace/'$(basename "$f" .txt)'/g' $f ; done – cas Mar 15 '16 at 23:35
  • The example is not written for efficiency. Explanation has priority over efficiency. – marc Mar 15 '16 at 23:39
  • Excessive complication undermines understanding. My simplification was not for the purpose of efficiency, it was to remove all the distracting and unnecessary complication in your example. – cas Mar 15 '16 at 23:42
find . -name "*" -type f | xargs sed -i -e "s/replace/On\ Time/g"

This will replace "all" text files under current dir(and subdirs) as you want.

If you want only in current directory and not in it's subdirs.

find . -name "*" -type f -maxdepth 1 | xargs sed -i -e "s/replace/On\ Time/g"

If you want to replace in a different directory from your current dir.

find /path/do/dir -name "*" -type f | xargs sed -i -e "s/replace/On\ Time/g"

Works for me on zsh shell. Should work on all else too.

| improve this answer | |
  • 1
    OP says "I have a large number of files"... Do you think all those files are named On Time.txt ? – don_crissti Mar 15 '16 at 22:41
  • Good point. Sorry, I guess I didn't read the question fully. – Sriram S Mar 15 '16 at 22:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.