0

I'm trying to rename some files while learning awk / xargs. I managed a command which gives me a file with two columns, the first one being the name of the file I want to rename, the second one being the name that file should end up with.
How can I split the content of a file (preferably using programs like awk / xargs) so that I can use each column as a variable?

The command

echo "foto1.JPG
foto2.JPG
foto3.JPG" | \
gawk '{ count++ }{ print $0 " " strftime("%y-%m-%d") "_" count ".JPG" }'  

outputs

foto1.JPG 21-11-09_1.JPG                                                
foto2.JPG 21-11-09_2.JPG
foto3.JPG 21-11-09_3.JPG

which is what I want but then I don't know how to separate and use its result. I tried

echo "foto1.JPG
foto2.JPG
foto3.JPG" | \                                                          
gawk '{ count++ }{ print $0 " " strftime("%y-%m-%d") "_" count ".JPG" }' | \
xargs -I% echo renaming $(echo % | awk '{ print $1 }') to $(echo % | awk '{ print $2 }') "..."

but it outputs

renaming foto1.JPG 21-11-09_1.JPG to ...                                                      
renaming foto2.JPG 21-11-09_2.JPG to ...
renaming foto3.JPG 21-11-09_3.JPG to ...

This conflicts me because

echo renaming $(echo foo bar | awk '{ print $1 }') to $(echo foo bar | awk '{ print $2 }') "..."

gives me

renaming foo to bar ...

and

echo "foto1.JPG
foto2.JPG
foto3.JPG" | \
gawk '{ count++ }{ print $0 " " strftime("%y-%m-%d") "_" count ".JPG" }' | \
xargs -I% echo this line has % in it

outputs

this line has foto1.JPG 21-11-09_1.JPG in it
this line has foto2.JPG 21-11-09_2.JPG in it
this line has foto3.JPG 21-11-09_3.JPG in it

I'm guessing there is something wrong with using the % inside the $( ... ) statement.

7
  • Why such a convoluted process? You could use a shell loop and the built-in date function!
    – Inian
    Nov 9, 2021 at 10:36
  • @Inian I want to understand better how to use pipes in general
    – ffigari
    Nov 9, 2021 at 10:37
  • 2
    Does this answer your question? Unexpected output of xargs
    – muru
    Nov 9, 2021 at 10:42
  • 1
    @ffigari which should convince you to not go around inventing Rube Goldberg systems to learn pipelines
    – muru
    Nov 9, 2021 at 10:49
  • 2
    | xargs -n2 mv
    – nezabudka
    Nov 9, 2021 at 11:10

1 Answer 1

1

You have no way to split the contents of the placeholder passed as part of -I AFAIK, you need to introduce a shell context to process the individual arguments here, i.e.

xargs -L1 sh -c 'renaming "$1" to "$2"' "$0"

The -L1 flag handles one multiline output piped to xargs at a time and the sh -c '..' runs the contents inside, with the whole line passed to it as arguments.


Tangentially, you don't need a separate counter variable for keep tracking unique line numbers. Awk already updates the current line number in the NR variable, which you could use as

gawk '{ print $0 " " strftime("%y-%m-%d") "_" NR ".JPG" }'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .