Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using backticks or $() with xargs and sed or awk

Tags:

bash

sed

awk

xargs

Assuming I want to change some filenames that end with jpg.jpg to end only with .jpg (in bash), and I want to do it by piping the output of find to xargs:

By using sed:

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | sed 's/jpg.jpg/.jpg/g')

However, this does not replace jpg.jpg with .jpg in the destination file of mv.

By using awk:

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | awk '{gsub(/jpg.jpg/,".jpg")}; 1')

This neither does any replacement. Have I missed something?

like image 645
nrz Avatar asked Oct 31 '12 21:10

nrz


3 Answers

I would do this by writing a script that takes filenames and does the rename:

#!/bin/sh

for FILE
do
    mv $FILE `basename $FILE jpg.jpg`.jpg
done

That script is easily called via xargs.

If you want to smash it onto a single command line you can do it but it's usually not worth the trouble.

EDIT: If I had to do it on one command line I'd probably use a different trick without xargs: Use sed to turn the output of find into a shell script:

find . -iname '*jpg.jpg' | sed -e 's/\(.*\)jpg\.jpg$/mv & \1.jpg/' | sh

The advantage of xargs being able to fork off fewer children is defeated by the need to run mv repeatedly anyway. If you really need that advantage you need a solution like my first option but coded in something like perl which can execute multiple rename() calls without forking off any mv.

like image 161
Ben Jackson Avatar answered Sep 29 '22 06:09

Ben Jackson


If you have the rename command available on your system, then the following command should work:

rename 's/(.*)jpg.jpg/$1.jpg/g' *jpg.jpg
like image 45
Sicco Avatar answered Sep 29 '22 07:09

Sicco


The $(...) is evaluated by bash before running xargs, so xargs just sees the output of that expression as it currently stands as the second argument to mv.

So it is equivalent to:

... | xargs -I % mv % %
like image 38
huon Avatar answered Sep 29 '22 05:09

huon