Sally Milson
Sally Milson

Reputation: 45

Piping grep to cut

This line:

echo $(grep Uid /proc/1/status) | cut -d ' ' -f 2

Produces output:

0

This line:

grep Uid /proc/1/status | cut -d ' ' -f 2

Produces output:

Uid:    0   0   0   0

My goal was the first output. My question is, why the second command does not produce the output I expected. Why am I required to echo it?

Upvotes: 2

Views: 5783

Answers (4)

user8854776
user8854776

Reputation: 201

grep Uid /proc/1/status |sed -r “s/\s+/ /g” | awk ‘{print $3}’

Output 0

Upvotes: 0

sjsam
sjsam

Reputation: 21965

One way to do this is to change the Output Field Separator or OFS variable in the bash shell

IFSOLD="$IFS" # IFS for Internal field separator
IFS=$'\t'
grep 'Uid' /proc/1/status | cut -f 2
0 # Your result
IFS="$IFSOLD"

or the easy way

grep 'Uid' /proc/1/status | cut -d $'\t' -f 2

Note : By the way tab is the default delim for cut as pointed out [ here ]

Upvotes: 2

dimo414
dimo414

Reputation: 48804

You should almost never need to write something like echo $(...) - it's almost equivalent to calling ... directly. Try echo "$(...)" (which you should always use) instead, and you'll see it behaves like ....

The reason is because when the $() command substitution is invoked without quotes the resulting string is split by Bash into separate arguments before being passed to echo, and echo outputs each argument separated by a single space, regardless of the whitespace generated by the command substitution (in your case tabs).

As sjsam suggested, if you want to cut tab-delimited output, just specify tabs as the delimiter instead of spaces:

cut -d $'\t' -f 2

Upvotes: 0

Diego Torres Milano
Diego Torres Milano

Reputation: 69198

Use awk

awk '/Uid/ { print $2; }' /proc/1/status

Upvotes: 2

Related Questions