How do I pipe a newline separated list as arguments to another command?

11,697

Solution 1

Use xargs:

mycommand | xargs -L1 id

Example:

$ (echo root; echo nobody) | xargs -L1 id
uid=0(root) gid=0(root) groups=0(root)
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

You can also loop over the input in bash:

mycommand | while read line
do
    id "$line"
done

xargs converts input to arguments of a command. The -L1 option tells xargs to use each line as a sole argument to an invocation of the command.

Solution 2

With bash, you can capture the lines of output into an array:

mapfile -t lines < <(mycommand)

And then iterate over them

for line in "${lines[@]}"; do
    id "$line"
done

This is not as concise as xargs, but if you need the lines for more than one thing, it's pretty useful.

Share:
11,697

Related videos on Youtube

yukashima huksay
Author by

yukashima huksay

Apparently, that user prefers to keep an air of mystery about them.

Updated on September 18, 2022

Comments

  • yukashima huksay
    yukashima huksay over 1 year

    So I have a list of usernames such as:

    user1
    user2
    user3
    

    I want to apply id on each of them and get something like:

    uid=100(user1) gid=5(g1) groups=5(g1),6(g6),7(g10)
    .
    .
    

    How can I achieve this? Please note that the list is the output of another command say mycommand.

  • yukashima huksay
    yukashima huksay over 6 years
    what does ` < <` mean?
  • fiatux
    fiatux over 6 years
    The first < is the usual redirection of mapfile's stdin. <(...) is a process substitution -- process substitutions are very useful to avoid issues due to pipelines running in subshells.
  • Seth Robertson
    Seth Robertson over 6 years
    If I know it is newline separated, and there is some danger that the input stream might contain spaces, I use '-d\n', as is: mycommand | xargs '-d\n' -L1 id Pretty much always a good idea, along with proper "$quoting" of all shell variables.
  • Olorin
    Olorin over 6 years
    @SethRobertson very true. I left off the -d '\n' and IFS= read -r since the input is said to be usernames, I felt it might be overkill.
  • Pablo Bianchi
    Pablo Bianchi about 4 years
    Maybe more clear: echo -n "root nobody" | tr ' ' '\n' | xargs -L 1 id