6

I want to grep 2 numbers from the same line in the example below:

// ExampleFile.txt
solver.cpp:229] Iteration 2000, loss = 0.305721
solver.cpp:245]     Train net output #0: accuracy = 0.926112
solver.cpp:245]     Train net output #1: accuracy = 0.723957
solver.cpp:245]     Train net output #2: accuracy = 0.599623
sgd_solver.cpp:106] Iteration 2000, lr = 0.000227383
solver.cpp:229] Iteration 2020, loss = 0.294722
solver.cpp:245]     Train net output #0: accuracy = 0.855208
solver.cpp:245]     Train net output #1: accuracy = 0.71616
solver.cpp:245]     Train net output #2: accuracy = 0.619429

I need the number to the right of "solver.cpp:229] Iteration " and to the right of ", loss = ". I need to get both numbers at the same time such that my resulting file looks like this:

// ResultFile.txt
2000 0.305721
2020 0.294722

I only know how to get one of the numbers using grep like this

grep ", loss = " ExampleFile.txt | sed -e "s/.* //" > ResultFile.txt

Does anyone know how to get the second number simultaneously?

1
  • Do you want the pair of numbers from only lines with "cpp:229"? Or do you also want the one with "cpp:106"? Nov 9, 2016 at 0:01

4 Answers 4

8

One possible way...

% grep 'solver.cpp:229' ExampleFile.txt | cut -d ' ' -f 3,6 | tr -d ','
2000 0.305721
2020 0.294722
2
  • It works. Thanks. I know that cut cuts the string at every ' ' (space). But what does the last command do? (tr -d ',')
    – mcExchange
    Nov 8, 2016 at 10:23
  • @mcExchange it deletes the comma that would otherwise remain
    – Zanna
    Nov 8, 2016 at 10:34
7

I lost grep but here it is with sed

$ sed -nr 's/.*Iteration ([0-9]+).*loss.*( [0-9]+.*)/\1\2/p' ExampleFile.txt
2000 0.305721
2020 0.294722
  • -n don't print until we ask for something
  • -r use ERE so I don't have to escape the () and + metacharacters
  • s search and replace /old/new/
  • .* matches any (or no) characters
  • ([0-9]+) parentheses to keep this part of the pattern [0-9] a number + one or more occurrences of the preceding character.
  • \1\2 backreferences to the patterns saved earlier with parentheses
  • p print the bits we want to see

If the output is what you want, redirect it to your outfile:

sed -nr 's/.*Iteration ([0-9]+).*loss.*( [0-9]+.*)/\1\2/p' ExampleFile.txt > ResultFile.txt
5

With awk specify Field separator as ',' comma and 'space' and match those lines which contain "Iteration" in, next print the columns #3 and #7 (or $NF as last column instead of $7)

awk -F'[, ]' '/Iteration/ {print $3,$7}' infile
1
perl -nE '/\].*?(\d+),.*loss = (\d+\.\d+)/ and say "$1 $2"' infile
  • if (line matches the regular expression), print the relevant groups.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.