21

I have a line of output from a command like this:

[]$ <command> | grep "Memory Limit"
Memory Limit:           12345 KB

I'm trying to pull out the 12345. The first step - separating by the colon - works fine

[]$ <command> | grep "Memory Limit" | cut -d ':' -f2
           12345 KB

Trying to separate this is what's tricky. How can I trim the whitespace so that cut -d ' ' -f1 returns "12345" rather than a blank?

user2824889
  • 1,085
  • 5
  • 16
  • 28

6 Answers6

24

Pipe your command to awk, print the 3rd column, a space and the 4th column like this

<command> | awk '{print $3, $4}'

This results in:

12345 KB

or

<command> | awk '{print $3}'

if you want the naked number.

John Goofy
  • 1,330
  • 1
  • 10
  • 20
  • I would suggest to replace `" "` with `,` as `awk` has a default `OFS` whose value is single space. Existing command is not wrong just having some unwarranted stuff in it. Example `awk '{print $3" " $4}'` and `awk '{print $3,$4}'` would result in same output in case of default `OFS`. – P.... Jun 02 '17 at 05:45
  • 2
    @PS. Of course you are right. Thanks a lot for the hint. I have made a change in my post. – John Goofy Jun 02 '17 at 11:24
11

tr helps here.

$ echo "Memory Limit:           12345 KB" | tr -s " " | cut -d " " -f3
12345
  • tr -s " " - squeeze all spaces into one
  • cut -d " " -f3 - split into columns by space and select third
anatoly techtonik
  • 19,847
  • 9
  • 124
  • 140
6

You can use awk and avoid using any cut, sed or regex:

<command> | awk '/Memory Limit/{print $(NF-1)}'

12345
  • /Memory Limit/ will make this print only a line with Memory Limit text
  • $(NF-1) will get you last-1th field in input.
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Presumably `` outputs more lines than the one containing "Memory Limit". It wouldn't be hard to make `awk` select that wanted line instead of using a separate `grep`, but you need to do one or the other. – John Bollinger Aug 05 '16 at 15:44
  • Yes in that case: ` | awk '/Memory/{print $(NF-1)}'` should work – anubhava Aug 05 '16 at 15:46
3

do you have to use cut? cut is only for single character delimiter extraction. i don't think cut can be as easy as you would expect.

sed is straightforward:

$ echo "Memory Limit:           12345 KB" | sed 's/.*:\s*//'
12345 KB

explanation:

.*:\s* matches all letters before the last colon, then matches all the empty chars after that and delete them by substituting to an empty string.


it turns out that you were expecting a single number. then i would say just go ahead and match the numbers:

$ echo "Memory Limit:           12345 KB" | grep -o -P '\d+'
12345
Jason Hu
  • 6,239
  • 1
  • 20
  • 41
1

awk is perhaps the best for this task, but here is an unorthodox way

$ grep -oP "(?<=Memory Limit:)\s+[0-9]+" file | xargs

lookbehind for matching the label and output only matching, use xargs to eat up spaces

karakfa
  • 66,216
  • 7
  • 41
  • 56
1

bash also has regular expression matching you can use.

result=$(<command> | grep "Memory Limit")
regex='Memory Limit:[[:space:]]+([[:digit:]]+)[[:space:]]KB'
if [[ $result =~ $regex ]]; then
  result=${BASH_REMATCH[0]}
else
  # deal with an unexpected result here
fi

The value of $regex can be adjusted as necessary.

chepner
  • 497,756
  • 71
  • 530
  • 681