Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a situation where I have some input files like this:

M2U0001.MPG
M2U0180.MPG

And I want to run a command (in a bash shell) on each similarly named file in the directory. I'd like the current file name to be given to this command as an input and a modified version of the filename to be given as an output file. Here's an example:

ffmpeg -i M2U0001.MPG M2U0001_fixed.MPG

I had the idea of using xargs and sed, but this is as far as I got:

ls -1 *.MPG | xargs -I{} ffmpeg -i {} `echo {} | sed -r 's/[0-9]{2,}/&_fixed/'`

But this results in the original filename being output in both positions. Am I totally going about this the wrong way?

I found that if I echo the filename directly to the embedded chunk like this it works:

echo M2U0001.MPG | sed -r 's/[0-9]{2,}/&_fixed/'
share|improve this question

3 Answers 3

up vote 4 down vote accepted

Or alternatively:

for i in *.MPG ; do ffmpeg -i $i `basename $i .MPG`_fixed.MPG ; done

Edit: Thank joshbaptiste for the hint.

share|improve this answer
    
This works perfectly. Thanks for the demonstration of a for-loop in a one-liner. –  Matthew Nov 12 '11 at 12:21
    
be aware of the fact that this command will fail on filenames that contain spaces –  Alex Nov 13 '11 at 0:38
    
True, I assumed file names are in that particular format, thanks for pointing it out. –  cYrus Nov 13 '11 at 10:30
find . -iname "*.mpg" -exec sh -c "ffmpeg -i {} `echo {} | sed -e 's/\./_fixed\./'`" \;
share|improve this answer
1  
This example does the same thing as my code. The original filename is used as both the input and output. –  Matthew Nov 12 '11 at 12:17

for i in $(ls) should not be used, ls(1) output should not be used for parsing via scripts etc.. due to word splitting and is a common mistake I see in bash scripts at my job.

In this case parameter expansion works fine and is not susceptible to word splitting errors.

for i in *.MPG; do ffmpeg -i "$i" "${i%%.*}"_fixed.MPG ; done

Reference: http://mywiki.wooledge.org/BashPitfalls

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.