4

Suppose I have 6 lines of text.

Series
Of
Word
73914
Again
Word

I need to prepend a string to the beginning of lines that contain ONLY numbers. Say I insert number-

Series
Of
Word
number-73914
Again
Word

Currently I run two commands to achieve the desired result. I wonder if there is a more efficient method.

Note: There are 1000+ lines, so preferably this applies to all lines ( I already state it ).

  • What do you want to do with a line like 1st word 2nd word? – glenn jackman Mar 29 at 18:00
  • And do you want only lines that are entirely a number or that start with a number? E.g. would you want 123abc to be changed to number-123abc or not? – Kevin Mar 29 at 19:57
9

sed can do that:

$ sed 's/^[[:digit:]]*$/number-&/' input.txt
Series
Of
Word
number-73914
Again
Word

In case we want to account for empty lines, we'd use + and -r option:

$ sed -r 's/^[[:digit:]]+$/number-&/' input.txt
Series
Of
Word
number-73914
Again
Word
line below is empty

line above is empty

Once you verify everything is proper, you can use -i option to edit the file itself, i.e. sed -i .... Otherwise, you can always make a copy of the file with sed 's/^[[:digit:]]*$/number-&/' input.txt > output.txt

Note that this assumes consistent file format, with no leading whitespaces or trailing whitespaces on each line.

And here's Python as extra:

$ python3 -c 'import sys; print("\n".join([ "number-" + i.strip() if i.strip().isnumeric() else i.strip() for i in sys.stdin]))' < input.txt
Series
Of
Word
number-73914
Again
Word
line below is empty

line above is empty
  • 2
    I often use the "substitute if match" variant for things like this /^[[:digit:]]+$/ s/^/number-/' – steeldriver Mar 29 at 7:29
  • Thanks for the complete instruction, I'm a total noob when it comes to text processing :-O – Jim Mar 29 at 9:41
4

One way using awk:

awk '/^[0-9]+$/{$0="number-"$0;}1'  file
  • I also seek awk solution, thanks ! 1+ – Jim Mar 29 at 9:42
3

lines that contain ONLY numbers

It's unclear whether you mean numbers or just 0-9. Here's a Perl one-liner that picks out the likes of 123, 3.14 and 1e-12 while ignoring various representations of infinity and not-a-number:

$ perl -MScalar::Util -ne 'chomp; if (!(m/^\s/ || m/^[\+-]?inf(?:inity)?$/i || m/^nan$/i) && Scalar::Util::looks_like_number($_)) { print("N:"); } print("$_\n");' <x
a
N:123
N:+1
N:-1
 1
b

1a
N:3.14
c
3.1415926 is an approximation of pi
N:1e-12
inf
Inf
Infinity
Infinity +1 sword
+Infinity
-infinity
NaN
1/2

I changed the prefix to "N:" simply because "number--1" looks a bit rubbish. Note that this treats " 1", for example, as not numeric. If that is undesirable behaviour, do not include the "m/^\s/" test for leading whitespace.

If you mean "0-9", Sergiy's sed solution above is fine.

  • Probably an overkill for this question, but still awesome ! +1 – Sergiy Kolodyazhnyy Mar 29 at 12:06
2

You can try this

$cat input.txt
Series
Of
Word
73914
Again
Word

$awk '{ if($1 ~/[0-9]/) printf "number - %s\n",$1; else print $1 }' input.txt
Series
Of
Word
number - 73914
Again
Word
  • Using if statement, nice ! Thank you :D – Jim Mar 29 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.