awk to update filename in directory

Viewed 300

In the below I am trying to use awk to change part of a pair of filenames (between the hyphen and underscore) in a directory with a value stored in a variable. The below does execute but the filenames do not change. Thank you :).

variable

id=aaaaa

files in directory

00-0000-xxx-y-zzz_x1_y.txt
00-0000-xxx-y-zzz_x2_y.txt

desired

00-0000-xxx-y-aaaaa_x1_y.txt
00-0000-xxx-y-aaaaa_x2_y.txt

awk

awk -F'-' var=$id'{sub("$5","var")}1' *.txt
3 Answers

Could you please try following(with pure bash solution), following will go through all .txt files and will print rename commands only on terminal. In case you are happy with results shown on terminal then append | bash to the solution. Note, please set id=aaaaa before running following commands.

for file in *.txt
do
   echo "mv $file ${file%-*}-${id}_${file#*_}"
done


Once you are happy with results above then run following to actually rename files to new file.

for file in *.txt
do
   echo "mv $file ${file%-*}-${id}_${file#*_}"
done | bash

awk is changing file content, not the file name itself.

Instead of awk, you may use rename perl utility like this:

id='aaaaa'
rename -n "s/^(.*)-[^_]+_/\$1-${id}_/" *.txt

'00-0000-xxx-y-zzz_x1_y.txt' would be renamed to '00-0000-xxx-y-aaaaa_x1_y.txt'

You can have awk create bash commands for you and then pipe the output of awk to bash.

ls *.txt | awk -F'[_-]' -vvar=$id '{f=$0 ; sub($5,var); print "mv", f, $0 } ' | bash

There were a number of fundamental issues.

  1. By passing *.txt to awk - awk will open each .txt file in your directory line by line. Rather, you wanted to just process the directory listing (so I added ls *.txt ).
  2. The variable var must be set with the -v option of awk.
  3. You didn't need to quote "$5" and "var". I suspect you pasted some old code into your question since you got it working.
  4. The field separator of - is insufficient. You'll lose the '_x1_y.txt' and '_x2_y.txt' portions of your file names. I added underscore as an additional field delimiter.

As a debugging tip, you can review what awk is going to do before taking any action:

$ ls *.txt | awk -F'[_-]' -vvar=$id '{f=$0 ; sub($5,var); print "mv", f, $0 } '
mv 00-0000-xxx-y-zzz_x1_y.txt 00-0000-xxx-y-aaaaa_x1_y.txt
mv 00-0000-xxx-y-zzz_x2_y.txt 00-0000-xxx-y-aaaaa_x2_y.txt

If the above looks good, just pipe the output to bash (as in the first code I provided ).

Related