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.
Related videos on Youtube
Author by
yukashima huksay
Apparently, that user prefers to keep an air of mystery about them.
Updated on September 18, 2022Comments
-
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 over 6 yearswhat does ` < <` mean?
-
fiatux over 6 yearsThe first
<
is the usual redirection ofmapfile
's stdin.<(...)
is a process substitution -- process substitutions are very useful to avoid issues due to pipelines running in subshells. -
Seth Robertson over 6 yearsIf 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 over 6 years@SethRobertson very true. I left off the
-d '\n'
andIFS= read -r
since the input is said to be usernames, I felt it might be overkill. -
Pablo Bianchi about 4 yearsMaybe more clear:
echo -n "root nobody" | tr ' ' '\n' | xargs -L 1 id