Your initial loop:
while read line; do
sed 's/[^0-9]//g'
done <listi.txt
What happens here is that the read
reads one line from the loop's input stream, which comes from the listi.txt
file. The value is stored into the variable line
(with some caveats) and not further used.
The call to sed
is then done without mentioning an input file, which means sed
will read from its standard input stream.
The standard input stream of sed
is inherited from the loop, so it reads and processes the second line from listi.txt
along with all other lines until the end of the file is reached.
The loop then executes read
again, but since there's nothing more to read, the call fails and the loop terminates.
The overall effect of the above is that the first line of the file listi.txt
is ignored, while sed
is processing the file from the second line onward, removing non-digits from each of these and outputting them to the terminal.
If you simply want to apply the sed
expression to all lines in listi.txt
, you would use
sed 's/[^0-9]//g' listi.txt
That is, there is no need to use a separate shell loop since sed
will apply its editing expression(s) to each line in the input file(s) by default.
If what you want to do is to delete all non-digits, then you may also do that with tr
, which is a tool that does single character transformations:
tr -d -c '0-9\n' <listi.txt
This deletes (-d
) any character from the input that is part of the complement (-c
) of the mentioned set of characters (0-9\n
; we probably want to keep the newline characters that divide the input into lines, which is why that is included here). The 0-9\n
bit could also be written [:digit:]\n
, which would match any digit in the current locale, and the newline character.
Also related:
sed
consumes/processes the remaining two lines. That's all. The proper way to do it issed 's/[^0-9]//g' listi.txt
, you don't needwhile..read
– don_crissti Feb 03 '23 at 11:36while read line
to begin with? – ilkkachu Feb 03 '23 at 11:50