2

I am trying to deal with the following situation. I have many files (more than 100) with an .html extension in a folder tree and inside those files I have a string which is the file name. For example I have the following files:

file1.html located in subfolder1/subfolderA/ which somewhere in the file contains the string file1.html.

file2.html located in subfolder1/subfolderB/ which somewhere in the file contains the string file2.html

file3.html located in subfolder2/subfolderC/ which somewhere in the file contains the string file3.html.

and so on.

Basically, I want to go through the entire tree structure, find the string which is identical to the file name and replace it with the path + file name, stripping the .html.

Therefore, in the example above, I want to replace:

  • in file file1.html:

    replace file1.html with subfolder1/subfolderA/file1

  • in file2.html:

    replace file2.html with subfolder1/subfolderB/file2

  • in file3.html:

    replace file3.html with subfolder2/subfolderC/file3

I know how to replace strings using find and sed. I used the following command:

find . -type f -name \*.html -exec sed -i.bak 's|<old string>|<new string>|g' {} +

However, in that case "old string" and "new string" need to be hard coded.

How can I achieve the above with

"old string" = the filename + file extension

"new string" = the path + filename - file extension

Any help will be greatly appreciated.

0

Since it is not a trivial task, I guess you will need a shell after -exec. Have a look at this:

#!/bin/sh
find . -type f -name "*.html" -exec sh -c '
  for file in "$@"; do
    filename=$(basename "$file")
    noext=${file%.*}
    noext=${noext#./}
    sed -i.bak "s|$filename|$noext|g" "$file"
  done
' findshell {} +

To generate the replacement string, it removes the extension with noext=${file%.*} and then removes the ./ of the relative path with noext=${noext#./}.

| improve this answer | |
  • Thank you for your pointers! – jopeto Mar 12 at 20:10
0

I'm afraid you can't do what you specify with find and exec alone. Try piping find's result into a small while loop:

find . -type f -name \*.html | while read PN; do sed "s|${PN##*/}|${PN%.*}|g" "$PN"; done
| improve this answer | |
  • This will fail on critically named files (special characters, blank spaces). Even with double-quoting "$PN", it won't be trick-proof. – Quasímodo Mar 12 at 16:57
  • Thank you for your pointers! – jopeto Mar 12 at 20:09
0

Tested and Worked fine

#!/bin/bash
echo "enter the input"
read p
cd $p
echo "enter the file"
read f
if [[ -f $p/$f ]]
then
echo "file exsists"

grep -io "$f" $p/$f >/dev/null
if [[ $? == 0 ]]
then
r=`echo $f | sed "s/\.txt//g"`
echo $r
awk -v f="$f" -v r="$r" '{gsub(f,r,$0);print }' $f 
fi
fi
| improve this answer | |

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.