1

I have to make a one-liner that renames all files in the current directory that end in ".hola" to ".txt".

For example:

sample.hola and name.hi.hola will be renamed to sample.txt and name.hi.txt respectively

I was thinking about something like:

ls -1 *.hola | awk '{NF="";print "$0.hola $0.txt"}' (*)

And then passing the stdin to xargs mv -T with a |

But the output of (*) for the example would be sample and name hi.

How do I get the output name.hi for name.hi.hola using awk?

German Robayo
  • 35
  • 2
  • 6
  • See http://stackoverflow.com/questions/13857836/display-all-fields-except-the-last. Then try `echo name.hi.hola | awk 'BEGIN{OFS=".";FS="."} {NF--;print}'`. You can adapt this to your example. Mark Reed's answer is appropriate for the problem you intend to solve. – zedfoxus Apr 03 '17 at 01:26
  • 1
    Note that modifying `NF` like that only works in GNU awk, not BSD/MacOS awk. – Mark Reed Apr 03 '17 at 01:28

3 Answers3

2

Why would you want to involve awk in this?

$ for f in *.hola; do echo mv "$f" "${f%hola}txt"; done
mv name.hi.hola name.hi.txt
mv sample.hola sample.txt

Remove the echo when you're happy with the output.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • I wanted the `awk` because it was for a homework, but now that i see your solution I didnt know that you can do `${f%hola}.txt` to substitute the "hola". Thanks! – German Robayo Apr 03 '17 at 12:44
1

Well, for your specific problem, I recommend the rename command. Depending on the version on your system, you can do either rename -s .hola .txt *.hola, or rename 's/\.hola$/.txt/' *.hola.

Also, you shouldn't use ls to get filenames. When you run ls *.hola, the shell expands *.hola to a list of all the filenames matching that pattern, and ls is just a glorified echo at that point. You can get the same result using e.g. printf '%s\n' *.hola without running any program outside the shell.

And your awk is missing any attempt to remove the .hola. If you have GNU awk, you can do something like this:

awk -F. '{old=$0; NF-=1; new=$0".txt"; print old" "new}'

That won't work on BSD/MacOS awk. In that case you can do something like this:

awk -F. '{
  old=$0; new=$1; 
  for (i=2;i<NF;++i) { new=new"."$i }; 
  print old" "new".txt"; }'

Either way, I'm sure @EdMorton probably has a better awk-based solution.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • Im in GNU and i tried your `awk` solution and I've got the same output, the dots in the input dissapear in `new`. I didnt knew about the `rename` comand, I think I'll have to investigate more. If I use `ls -1 *.hola` it will list all in column. – German Robayo Apr 03 '17 at 12:55
  • `printf '%s\n' *.hola` also outputs in a column – Mark Reed Apr 03 '17 at 14:57
0

How about this? Simple and straightforward:

for file in *.hola; do mv "$file" "${file/%hola/txt}"; done
reflective_mind
  • 1,475
  • 3
  • 15
  • 28
  • mmmm I think I should learn more about the `bash` commandline. I did not knowthat `${file/%hola/text}` will replace those "hola's". I think that the solution was using `awk` because it was for a homework about it. – German Robayo Apr 03 '17 at 12:57