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?


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?

  • 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


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
  • 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

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.


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-
  • 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

Using cut to extract all fields after 3:

grep -o 'created files:' $logfile | cut -d" " -f3-
  • 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 .