开发者

How do I send multiple results from one command to another in bash?

开发者 https://www.devze.com 2023-01-10 16:38 出处:网络
I\'m not sure if this is possible in one line (i.e., without writing a script), but I want to run an ls | grep command and then for each result, pipe it to another command.

I'm not sure if this is possible in one line (i.e., without writing a script), but I want to run an ls | grep command and then for each result, pipe it to another command.

To be specific, I've got a directory full of images and I only want to view certain ones. I can filter the images I'm interested in with ls | grep -开发者_开发百科i <something>, which will return a list of matching files. Then for each file, I want to view it by passing it in to eog.

I've tried simply passing the results in to eog like so:

eog $(ls | grep -i <something>)

This doesn't quite work as it will only open the first entry in the result list.

So, how can I execute eog FILENAME for each entry in the result list without having to bundle this operation into a script?

Edit: As suggested in the answers, I can use a for loop like so:

for i in 'ls | grep -i ...'; do eog $i; done

This works, but the loop waits to iterate until I close the currently opened eog instance.

Ideally I'd like for n instances of eog to open all at once, where n is the number of results returned from my ls | grep command. Is this possible?

Thanks everybody!


I would use xargs:

$ ls | grep -i <something> | xargs -n 1 eog


A bare ls piped into grep is sort of redundant given arbitrary?sh*ll-glo[bB] patterns (unless there are too many matches to fit on a command line in which case the find | xargs combinations in other answers should be used.

eog is happy to take multiple file names so

eog pr0n*really-dirty.series?????.jpg

is fine and simpler.


Use find:

find . -mindepth 1 -maxdepth 1 -regex '...' -exec eog '{}' ';'

or

find . -mindepth 1 -maxdepth 1 -regex '...' -print0 | xargs -0 -n 1 eog

If the pattern is not too complex, then globbing is possible, making the call much easier:

for file in *.png
do
  eog -- "$file"
done

Bash also has builtin regex support:

pattern='.+\.png'
for file in *
do
  [[ $file =~ $pattern ]] && eog -- "$file"
done

Never use ls in scripts, and never use grep to filter file names.


#!/bin/bash
shopt -s nullglob
for image in *pattern*
do
  eog "$image"
done

Bash 4

#!/bin/bash
shopt -s nullglob
shopt -s globstar
for image in **/*pattern*
do
    eog "$image"
done


Try looping over the results:

for i in `ls | grep -i <something>`; do
    eog $i
done

Or you can one-line it:

for i in `ls | grep -i <something>`; do eog $i; done

Edit: If you want the eog instances to open in parallel, launch each in a new process with eog $i &. The updated one-liner would then read:

for i in `ls | grep -i <something>`; do (eog $i &); done


If you want more control over the number of arguments passed on to eog, you may use "xargs -L" in combination with "bash -c":

printf "%s\n" {1..10} | xargs -L 5 bash -c 'echo "$@"' arg0

ls | grep -i <something> | xargs -L 5 bash -c 'eog "$@"' arg0
0

精彩评论

暂无评论...
验证码 换一张
取 消