awk to rename files in directory based on string match in another file

Viewed 23

I am trying to use awk to rename all .txt files in a directory based on a match to a column in a file. That is the string before the the .txt will be an exact match to $2 of file, the text file is then renamed with the $1 value. he awk does execute, but not with the desired result. Thank you :).

current directory structure

123_1.txt
456_2.txt
789_3.txt

file

aaa 123_1
bbb 456_2
ccc 789_3

awk

ls *.txt | awk -vvar=$2 '{f=$1 ; sub($2,var); print "mv", f, $0 } ' file

current

mv aaa 123_1 aaa
mv bbb 456_2 bbb
mv ccc 789_3 ccc

desired directory

aaa.txt
bbb.txt
ccc.txt
1 Answers

To simulate ls *.txt in my environment:

$ cat directory.list
123_1.txt
456_2.txt
789_3.txt

One awk idea:

cat directory.list | 
awk '
FNR==NR { map[$2]=$1; next }                               # needs additional work if either filename contains embedded spaces, newlines, odd characters
        { split($0,a,".")                                  # needs additional work if filename contains more than one period
          if (a[1] in map)
             print "mv \"" $0 "\" \"" map[a[1]] ".txt\""   # add double quote wrappers in case filenames contain white space, though OP will need to improve/fix earlier map[] and split() operations to support embedded white space
        }
' file -                                                   # the hyphen says to read stdin as the 2nd input file to the awk script

This generates:

mv "123_1.txt" "aaa.txt"
mv "456_2.txt" "bbb.txt"
mv "789_3.txt" "ccc.txt"

NOTES:

  • this doesn't address the (obvious ?) issues of processing ls output (eg, filenames with odd characters, embedded linefeeds, etc)
  • this doesn't actually perform the mv command (I'm just repeating what OP's current code does); to have awk perform the actual mv will require issuing a system(...) call; if OP has issues getting a system(...) call to work I'd recommend a new question
  • this is one of those operations where a bash loop may be easier (eg, load file into an associative array and then process ls/find output with a while/read loop)
Related