3

I am trying to modify some files as this:

  • Replacing a given word with another one using awk statement.
  • Both of words must be variables in awk.

I tried something like this, but my code does not work properly.

read word                                 
read replace                     
while read file                         
do     
   if [[ -f $file ]]           
       then       
       awk -v cuv1="$word" -v cuv2="$replace" '{gsub(/cuv1/,"cuv2")}' "$file"   
   else   
       echo "File does not exist"   
   fi     
done    

What should I do?

  • 3
    When asking a question, simply stating that "it doesn't work" is essentially useless. You need to explain i) what the code is supposed to do and ii) what it actually does. Also, please explain what the while read file is doing. how are you giving data to the loop? Finally, why awk? It can do this but it isn't particularly well suited for the job. Are you open to solutions using different tools? – terdon Apr 6 '17 at 12:43
  • while i am reading files, i want to modify them(i used while because i do not care how many file i want to modify). Unfortunately, i have to use awk. My readed words, word and replace, will be the parameters for awk. Then, for every file, i want to replace "word" with "replace" and to update the file that i have modified. My code does not return me an error, but it does not modify my files. – Robert Corman Apr 6 '17 at 12:54
  • 1
    No of course not. Even if your command were correct, awk wouldn't modify the file, only print out the changed contents (newer versions of GNU awk can do this but never mind). Please edit your question and explain how you are feeding the while loop. As it is, it will never work. And please explain why you need awk. – terdon Apr 6 '17 at 12:56
2

The basic error you have is that gsub(/cuv1/, "cuv2") will not look for the variables, it will look for the string cuv1 and replace it with cuv2. To use the variables, you want:

gsub(cuv1,cuv2);

The next problem is that you're not actually telling awk to print anything. The default action of awk when an expression evaluates to true is to print the line, so your command (with the fix above) will print any lines where the replacement worked, but not any others.

Finally, you seem to be expecting that awk will make the change top the original file. For that, you need the GNU awk (gawk) extension -i inplace. That, however, is relatively new and not portable. It won't work on all systems. Putting all this together, we get (assuming GNU awk):

awk -i inplace  -v cuv1="$word" -v cuv2="$replace" '{gsub(cuv1,cuv2); print;}' "$file"

Simpler solutions using sed and perl:

sed -i "s/$word/$replace/g" "$file"
perl -i -pe "s/$word/$replace/g" "$file"
  • The exercise must be solved with awk. I know it would be much easier to work with sed or perl. The code that you wrote works perfectly! Thank you very much for helping me! Have a nice day! – Robert Corman Apr 6 '17 at 13:10
  • @RobertCorman if it's to be solved with awk, are you sure you're not expected to look for the data in specific fields? That's what awk is for, after all. – terdon Apr 6 '17 at 13:13
  • Yes, i am sure. I must loop through entire file and to replace a given word with another one. – Robert Corman Apr 6 '17 at 13:16
  • What about only whole word substitution? For example: word='abc' and replace ='def'. If my file containts: abc abcdef zzabc, i want to modify it like this: def abcdef zzabc. – Robert Corman Apr 6 '17 at 13:34
  • @RobertCorman then you use the right tool for the job and that's not awk. If this is what is expected of you, either your teacher is an idiot or you have misunderstood the assignment and you're supposed to replace in specific fields. There really is no reason to use awk if you don't want to take advantage of its field-manipulating capability. – terdon Apr 6 '17 at 14:05

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.