1

I mean some command subtitutions. In the past I was able to use backticks in Bash, when for example I had to download a list of files / links which had been already collected in a text file, line by line:

wget `cat list.txt`

and even megadl to download from mega:

megadl `cat list.txt`

Unfortunately it doesn't work right now as expected for some reason. I get the whole file list as a long line of text separated by spaces instead of newlines.

I often write small scripts which can handle only one argument which is a file, but not a list of files, listed in a text file. Of course I don't want to modify my scripts, because Bash provide this helper mechanism, to apply the same command to a list of files, for example on the output of "ls -1 *.jpg". I have a small utility called "cgamma" which apply gamma correction to image files while preserving the colour saturation ( it simply calls imagemagick's mogrify). And I would like to use it on many image files, like this:

cgamma `ls -1 *.jpg` 1.3

I know I could use a for loop one-liner, but it is more typing:

for $i in $(ls -1 *.jpg);do cgamma $i 1.3;done

So my question is, how can I use properly the backticks, command substitution, to process file lists, and apply the same command to all of them?

Rakholiya Jenish
  • 3,165
  • 18
  • 28
Konstantin
  • 2,983
  • 3
  • 33
  • 55

2 Answers2

3

You can use xargs:

printf '%s\0' *.jpg | xargs -0 -I {} cgamma '{}' 1.3
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

You can actually shorten your putative for loop by using bash to do the globbing for you - rather than parsing the output of ls which is best avoided:

for i in *.jpg; do cgamma "$i" 1.3; done

That is actually shorter than your accepted solution :-)

Further, you could use GNU Parallel and not only make the command shorter, but also have them all gamma-corrected in parallel and make use of all those lovely Intel cores you paid top dollar for ;-)

parallel cgamma {} 1.3 ::: *.jpg
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432