1

I am trying to replace every occurrence in a .prm file of the string "/net/origin/devdata1/slin" with "/tools/common/test/HATS" in over a hundred files using sed. I think I am having trouble with the proper syntax for a for loop that loops through different files in a directory(/home/AutoTest), and what/if I need as command line arguments. Thanks in advance.

OLD="/net/origin/devdata1/slin" 
NEW="/toolscommon/test/HATS" 
DIR="/home/AutoTest" 
for f in $DIR 
do 
    cp $f $f.bak 
   sed 's+$OLD+$NEW+g' $f.bak > $f 
   [ -f "$f" ] 
   rm -f $f.bak 
done
dhboots
  • 21
  • 3
  • 2
    You will get a much more friendly reception and much better help here if you show what code you have tried so far and describe what problems you were having with it. Without code, your question looks like a request for free consulting and many people don't like that. – John1024 Jan 10 '18 at 20:42
  • Of course. Here is what I tried (very amateur since I'm not a pro at sh scripting) – dhboots Jan 10 '18 at 20:50
  • 2
    See: [Difference between single and double quotes in bash](http://stackoverflow.com/q/6697753/3776858) – Cyrus Jan 10 '18 at 21:05
  • Also, what OS are you using? Linux, OSX, other? – John1024 Jan 10 '18 at 21:06
  • 1
    I'm using Unix @John1024 – dhboots Jan 10 '18 at 21:08
  • Is `[ -f "$f" ]` intended to do something? Currently, it evaluates whether the file exists but has no affect on the script. Perhaps you intended to write `[ -f "$f" ] && rm -f $f.bak` – William Pursell Jan 10 '18 at 21:13
  • Possible duplicate of [sed substitution with bash variables](https://stackoverflow.com/questions/7680504/sed-substitution-with-bash-variables) – Benjamin W. Jan 10 '18 at 21:15
  • I generally find these sort of things easier with a shell command one-liner using `find`... something along the lines of `find . -name \*.prm -exec sed -i '.bak' 'whatever sed commands' {} +` ... rather than writing a script that has to do the looping itself. – Stephen P Jan 10 '18 at 21:18

1 Answers1

0

Using sed

Try:

old="/net/origin/devdata1/slin"
new="/toolscommon/test/HATS"
dir="/home/AutoTest"
sed -i "s+$old+$new+g" "$dir"/*

sed -i will update files in-place.

Also, it is best practices to use lower or mixed case names for your shell variables. The system uses all-caps names for its variables and you don't want to accidentally overwrite one of them.

There is a potential danger here if old or new contained any sed-active characters. If so, arbitrary files could be deleted or mangled.

Using awk

old="/net/origin/devdata1/slin"
new="/toolscommon/test/HATS"
dir="/home/AutoTest"
awk -i inplace -v old="$old" -v new="$new" '{gsub(old, new)} 1' "$dir"/*

Because awk treats old and new as data and not code, this is safer than the sed version.

John1024
  • 97,609
  • 11
  • 105
  • 133