1

ok, this is driving me crazy! I am trying to grep some info from a log file and add it to a summary in a email notification.

from log:

2019/07/22 11:36:03 [14396] Number of created files: 3 (reg: 2, dir: 1)

Now I want the print to be only the numbers at the end, 3, 2, 1 or maybe the entire last part 3 (reg: 2, dir: 1)

I have tried different things and this is the closest I got, but it only prints the number 3 and not the rest of the info I want.

nf=$(grep -o 'created files:' $logfile) | cut -d\   -f3)

Is this possible at all?

Edit:

Ok, so I got it working using nf=$(grep -Po 'created files: \K.*' "$logfile")

In my summary I add $nf to get the output like this Created $nf new files giving me this result

Created 3 (reg: 2, dir: 1) new files

Now, can I somehow split it up even more so my result will be something like this? Created 1 directory and 2 files

Maybe using two separate grep commands to output the different variables, one for dir and one for reg on that line?

1
  • That last command should have grep -o 'created files:.*' or grep 'created files:' since grep -o with a constant string pattern would only print that string.
    – ilkkachu
    Jul 22, 2019 at 10:38

4 Answers 4

4

If your grep supports perl-compatible regular expressions (PCRE):

$ grep -Po 'created files: \K.*' "$logfile"
3 (reg: 2, dir: 1)

To save the numbers into a bash array:

$ numbers=( $(grep -o 'created files:.*' "$logfile" | grep -o '[0-9]\+') )
$ echo ${numbers[@]}
3 2 1
$ echo "${numbers[0]}, ${numbers[1]}, ${numbers[2]}"
3, 2, 1
3
  • The first part worked. Can you please explain what the different part in that command does? Jul 22, 2019 at 10:43
  • With the -P option you can use \K to match the whole pattern, but created files: is not included in the output. Only everything after that is in the output (.*).
    – Freddy
    Jul 22, 2019 at 11:18
  • What's the output of the second example? Are you using a different shell?
    – Freddy
    Jul 22, 2019 at 12:22
1

Perl to the rescue:

$ perl -ne 'print "$1 $2 $3\n" if /created files: (\d+) \(reg: (\d+), dir: (\d+)\)/' < "$logfile"
3 2 1

or with sed:

$ sed -nEe 's/.*created files: ([0-9]+) \(reg: ([0-9]+), dir: ([0-9]+)\)/\1 \2 \3/p' "$logfile"
3 2 1

Both do mainly the same thing: match the whole ending part of the line (not just created files), but capture (with (...)) the numbers and print them or replace the line with them.

0

To fix your command:

  • Add .* to the pattern to include the rest of the line in your grep output.
  • Use -f3- to select all fields from 3rd to the end.

-->

grep -o 'created files: .*' "$logfile" | cut -d\  -f3-
2
  • 1
    ok, so f3 prints only field3, while -f3- prints field 3 and to the end of the line? Jul 22, 2019 at 11:33
  • exactly! you can use e.g. -f3-6 to select fields 3 to 6, but if you omit the 6, it just selects all fields til the end.
    – pLumo
    Jul 22, 2019 at 11:41
0

Using cut to extract all fields after 3:

grep -o 'created files:' $logfile | cut -d" " -f3-
1
  • I tried this but it dont give any output at all Jul 22, 2019 at 10:35

You must log in to answer this question.

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