localhost
localhost

Reputation: 1273

How to use xargs to run bash -c on filenames with both single and double quotes

I am trying to use xargs to run ffmpeg on every file in a folder and output the names of files that have vorbis audio.

I have come up with the following that mostly works, but it fails on files that have single quotes in the filename.

find . -maxdepth 1 | onlyvideos | tr '\n' '\0' | xargs -n1 -0 -I '{}' bash -c "if ( ffmpeg -i '{}' 2>&1 | grep Stream | grep -q vorbis ) ; then echo '{}' ; fi;"

onlyvideos is a script I have written that only prints the names of files with video extensions to stdout.

How can I get xargs to run bash -c on filenames that might include either or both single and double quotes?

Upvotes: 0

Views: 475

Answers (2)

Renaud Pacalet
Renaud Pacalet

Reputation: 29040

All this could be simplified a lot, probably, but if you want to stick with your onlyvideos script you could try:

find . -maxdepth 1 | onlyvideos | tr '\n' '\0' |
  xargs -n1 -0 bash -c 'if ( ffmpeg -i "$1" 2>&1 | grep Stream | grep -q vorbis ) ; then echo "$1" ; fi;' bash

Explanation: bash -c 'cmd' arg0 arg1 executes cmd with position parameters set to $0=arg0 (bash in our case) and $1=arg1 (the file name in our case, passed by xargs). So, using "$1" in your command script 'cmd' should work as you expect.

Upvotes: 2

emptyhua
emptyhua

Reputation: 6692

A while style

find . -maxdepth 1 | onlyvideos | while read f; do if ( ffmpeg -i "$f" 2>&1 | grep Stream | grep -q vorbis ) ; then echo "$f" ; fi; done

Upvotes: 1

Related Questions