1

Trying to run these operations in a bunch of files:

 1. Swap field position and pad numbers if necessary
 2. Trim file name fields to initials
 3. Adjust -

a minimal example would be something like;

from this:

01 - Some - Else - Edu.txt
02 - Some thing - Else where - Edu.txt
3 - SOME THING - ELSE WHERE - Edu.txt

to this:

S-E - 01 - Edu.txt
St-Ew - 02 - Edu.txt
ST-EW - 03 - Edu.txt

How can I do it with (g)awk (or in conjunction with other tools, if needed) ??

  • 5
    Welcome to SO, please do add your efforts in form of code in your question, thank you – RavinderSingh13 Jul 07 '21 at 18:45
  • 1
    `perl -e 'for(@ARGV){($n,$m,$s)=/^(\d+) +- +(.*)(- .*)$/ or next; $m=~s/(.).*? +/$1/g; rename$_,sprintf"$m - %02d $s",$n}' *.txt` – jhnc Jul 08 '21 at 03:48
  • @jhnc Thank you sir, was trying to do something with perl's rename aswell, but my inability to properly understand the docs capped my efforts greatly, also I'm sick of reading basic examples that take me nowhere. – Renato D.O. Jul 08 '21 at 12:01
  • m// above can accept invalid input. regexp should be `/^(\d+) +- +(.* )(- .*)$/` (ie. add explicit space after first `.*`). This avoids mangled output if the subsequent s/// doesn't see a trailing space. eg: `01 - Some - Else- Edu.txt` should be ignored but with original regexp would become `S-Else - 01 - Edu.txt` – jhnc Jul 08 '21 at 16:18

1 Answers1

0

Create tst.awk file:

$ cat tst.awk 
    {if(NF=="7") printf "%s-%s - %02d - %s\n", substr($3,1,1), substr($5,1,1), $1, $7
     if(NF=="9") printf "%s%s-%s%s - %02d - %s\n", substr($3,1,1), substr($4,1,1), substr($6,1,1), substr($7,1,1), $1, $9}

bash one-liner

$ for file in *Edu.txt ; do newfilename=`awk -f tst.awk <<<"$file"`; echo mv "$file" "$newfilename"; done
  • Note that echo before mv is to safely preview resulting command. Remove echo to run actual mv command.
  • awk.tst is created to keep terminal screen clean and for later modifications. so in terminal you only run awk.tst file in one-liner instead of whole awk code
  • This works with the given sample file pattern. If there are any file that contains more than two words between - then simply add if condition line in awk file as NF=="#" whereas # is number of words between each space and edit printf formatting accordingly.

Below is the list of what was there in current working directory before:

$ find .
.
./tst.awk
./01 - Some - Else - Edu.txt
./02 - Some thing - Else where - Edu.txt
./3 - SOME THING - ELSE WHERE - Edu.txt

Resulting Output

$ find .
.
./tst.awk
./S-E - 01 - Edu.txt
./St-Ew - 02 - Edu.txt
./ST-EW - 03 - Edu.txt

also see here for other methods AWK, SED, REGEX to rename files

  • Looks great, can you explain how to use it directly into the files, instead of an input file? – Renato D.O. Jul 08 '21 at 11:57
  • do you mean like "applying to files under a directory instead of one file" or "apply to matching specific lines in a file" please add more detail and share some samples for better understanding. – Ahmet Said Akbulut Jul 08 '21 at 13:26
  • @AhmetSaidAkbulut "applying to files under a directory instead of one file" exactly that – Renato D.O. Jul 08 '21 at 20:34
  • @RenatoD.O. does this answer your question? – Ahmet Said Akbulut Jul 09 '21 at 06:41
  • Got a syntax error at line 1 (unexpected token next to {if(NF=="7")) but I did accepted the answer. – Renato D.O. Jul 10 '21 at 22:40
  • Thank you but I try to figure out and works perfectly fine for me. you may try this out as it is a plain one-liner without tst.awk `for file in *Edu.txt ; do newfilename=$(awk '{if(NF=="7") printf "%s-%s - %02d - %s\n", substr($3,1,1), substr($5,1,1), $1, $7; if(NF=="9") printf "%s%s-%s%s - %02d - %s\n", substr($3,1,1), substr($4,1,1), substr($6,1,1), substr($7,1,1), $1, $9}' <<<"$file"); echo mv "$file" "$newfilename"; done` – Ahmet Said Akbulut Jul 10 '21 at 23:18
  • Very interesting though... above tested code in the comment may be more consistent for you. Apart from that, I run out of ideas... – Ahmet Said Akbulut Jul 10 '21 at 23:19