0

I am trying to print a portion of an output from a command:

cat script.sh | grep Xmx 

java -jar -Duser.language=en -Djava.awt.headless=true -Xms1024m -Xmx1024m -Dspring.profiles -Dspring.cloud.config.uri ...*

I need to only list out -Xms1024m -Xmx1024m.

I cannot use awk or cut because I need to run this across various services and the script is different.

I tried using sed to pick the string between 2 characters (like true and -Dspring) sed -e 's/.*true\(.*\)-Dspring/\1/', but that didn't work. Reason it didnt work because the scripts are different for each services. Some have the flags "-Djava.awt.headless=true" in it & others dont.

Please provide some insight on the correct sed syntax to use.

8
  • What's your key to know what to select? Is it text that begins with Xmx or that it's the two "words" after true? Please edit your question to explain how we are supposed to extract the required text Commented Mar 23, 2020 at 22:10
  • Is this for Linux-based (GNU grep-based) systems? Or others? Commented Mar 23, 2020 at 22:11
  • Does the output always appear like that? Do you just need to extract the exact same strings, -Xms1024m -Xmx1024m, no matter what? Might they appear multiple times? Commented Mar 23, 2020 at 22:16
  • If the script is always different, what makes you so sure the data that you want is on the same line as the substring Xmx? The java command could well span multiple lines.
    – Kusalananda
    Commented Mar 23, 2020 at 22:27
  • This is for Linux system.
    – Tony Jose
    Commented Mar 23, 2020 at 22:36

3 Answers 3

3

Based on your comments above, you'll always have the two arguments next to each other and I am assuming that the order will be as shown, you could use the following command:

sed -n -e 's/.*\s\(-Xms\S*\s*-Xmx\S*\).*/\1/p' script.sh

Here's what is going on:

  • The -n flag suppresses printing any output, but the p at the end of the sed expression will print anything that matches the rule.

  • The expression uses \s for a white space character and \S for a non-white space character.

  • The first part of the expression .*\s should capture the start of the line up to a white space character before the pattern in parenthesis (the capture group)

  • -Xms\S* will match the first argument. It will start with -Xms and the \S* will match anything up to whitespace (e.g., "1000m" or "1.5G")

  • \s* there is 0 or more whitespace characters (could make it \s\s* to guarantee there is separation)

  • -Xmx\S* match the second parameter you want, again up to the next bit of whitespace

  • The we close the capture group and ignore the rest of the line, substituting with just the capture group.

There probably are another dozen ways you could do the regular expression, but this was what first came to mind and worked when I tested it.

2
  • Thank you very much. This worked perfectly. On a separate note - What should be the syntax if I am trying to capture something that is in between 2 other strings. I tried this: sed -e 's/.*<string1>(.*)<string2>/\1/' It prints everything after string1 but included everything after string2 as well. What did I miss.
    – Tony Jose
    Commented Mar 24, 2020 at 5:34
  • @TonyJose - Glad this worked for you. Just FYI, you should mark the answer as "accepted". In terms of your other question, the sed s expression is doing a substitution. The pattern you are matching includes the beginning of the line with the .* pattern up to the "<string2>" which it replaces with what is inside the capture group. Since you didn't include the rest of the line in your pattern, it is left the same. Try adding a .* to the end of your pattern (after "<string2>") which will match the rest of the line as well. Commented Mar 24, 2020 at 17:48
1

As the two strings are always going to appear next to each other you can use this:

grep -o "\-Xms[0-9]*[g,m].*[0-9][g,m]" script.sh

Output:

-Xms1024m -Xmx1024m

This will work even if it's -Xms256m or -Xmx4096m or even if it's specified in gigabytes such as -Xms1g or -Xmx8g. You can run it directly on the file or on ouptut.

1
  • Thank you Nasir.
    – Tony Jose
    Commented Mar 24, 2020 at 5:16
0

You can try with grep:

grep -o "\-Xms[0-9]*m \-Xmx[0-9]*m" file

Output

-Xms1024m -Xmx1024m
3
  • - Thank you. This worked like a charm. So can I use the same pattern to print any number of strings I need ... Like grep -o "\<pattern1>*m \<pattern2>*m \<pattern3>*m" foo
    – Tony Jose
    Commented Mar 23, 2020 at 23:18
  • @TonyJose I would say yes, but without having a look at them can't tell you for sure. But yes, you can follow that structure. In any case you can try new patterns, and if in trouble, we can see it about. Commented Mar 23, 2020 at 23:24
  • appreciate your help
    – Tony Jose
    Commented Mar 24, 2020 at 5:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .