0

Using Bash, I want to display the number of lines that contain at least one number (a number is only made of one or several digits) in an arbitrary text.
I also want to display detected numbers one to a line. Provided is an example of a text file, example.txt, along with the desired output.

$ cat example.txt
Electronic mail is a method of exchanging digital messages between computer 
users; such messaging first entered substantial
use in the 1960s and by the 1970s had taken the form now recognised as email. 
These are spams email ids: 

08av , 29809, pankajdhaka.dav, 165 .

23673 ; meetshrotriya;  221965; 1592yahoo.in
[email protected]
[email protected]
[email protected]
[email protected]

[email protected]
These are incorrect:

065
kartikkumar781r2#
1975, 123

Desired output:

Number of lines having one or more digits are: 4
Digits found:
29809
165
23673
221965
065
1975
123
2
  • Hello. It's common practice when you review solutions to acknowledge them and to signal your favorite or the best one with a green check mark in the left margin of said solution. It signals to others in the community that there is a solved issue with a valid solution available to them, if perchance they ran in the same issue. --- In this case I have no issue pointing to @αғsнιη 's solution as the better one. It is built on the same pattern I chose earlier but it is shorter more elegant and easier to understand. Say thanks to αғsнιη ! Cheers.
    – Cbhihe
    Apr 19, 2021 at 14:27
  • Please explain more clearly why “1960”, “08” and “29”, etc., do not qualify. What should be done with “4/19/2021”, “12:34:56”, “#1”, “17!”, “5+12=17”, “$42”, “98.6°” or “sqrt(2.25)”? … … … … … … … … … … … … … … … … … … … … … … … … Please do not respond in comments; edit your question to make it clearer and more complete. Apr 19, 2021 at 17:10

4 Answers 4

1

try:

printf '
Number of lines having one or more digits are: %d
Digits found:
%s
' "$(grep -Ecw '[[:digit:]]+' infile)" "$(grep -Eow '[[:digit:]]+' infile)"
0
0

This answer is based on your provided example.
It means that if numbers are interspersed in file example.txt with separators that differ from either space, , or ; the script will probably give you incomplete results. In any case, I generalize this solution to separation patterns that allows any combination of space(s), comma(s) and semicolon(s). Adding different separators is trivial in case you need them.

$ cat my_script.bash
#!/usr/bin/env bash

printf "Number of lines having one or more digits is: %s\n" \
    "$(grep -cE '(^| )[0-9]+( |,|;|$)' $1)"
printf "Digits found:\n"
printf "%s\n" "$(sed -E 's/ |\,|\;//g;' < <(grep -o -E '(^|( *|,|;)+)[0-9]+( |,|;|$)' $1))"

I am sure that it is possible to do entirely with sed, but grep was all too tempting in that context.

To use, make the file my_script.bash executable and run:

$ chmod ug+x my_script.bash

$ my_script.bash example.txt
Number of lines having one or more digits are: 4
Digits found:
29809
165
23673
221965
065
1975
123 
0

How about (GNU grep, because of the \< and \>):

$ grep -o '\<[0-9][0-9]*\>' example.txt 


29809
165
23673
221965
065
1975
123

1
  • The GNUism here is -o, \< and \> are from ex in the 70s I believe (and were in some other grep implementations before GNU's). The implementations that have \<...\> also have -w (which initially was implemented by adding \<...\> around the regexp(s)). Nov 10, 2023 at 16:17
0

With perl:

perl -lne '
  if (@n = /\b\d+\b/g) {push @all, @n; $n++}
  END {print for "$n line(s) with numbers. Number(s):", @all}
  ' your-file

That's sequences of 1 or more (+) ASCII decimal digits, preceded and followed by a word boundary or IOW neither preceded nor followed by ASCII word characters (a-zA-Z0-9_).

You must log in to answer this question.

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