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.

You must log in to answer this question.

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