0

I have to make a regex to match one digit only. it should match 7 and a7b but not 77. I made this but it doesn`t seem to work in sed.

(?<![\d])(?<![\S])[1](?![^\s.,?!])(?!^[\d]) 
(?<![\d])(?<!^[\a-z])\d(?![^a-z])(?!^[\d])

What am I doing wrong?

Edit:

I need to replace only 1-digit numbers with something like

sed 's/regex/@/g' file //regex to match "1"

file content

1 2 3 4 5 11 1
agdse1tg1xw 
6 97 45 12 

Should become

 @ 2 3 4 5 11 @ 
 agdse@tg@xw 
 6 97 45 12 

3 Answers3

1

Input

a77
a7b
2ab
882
9
abcfg9
9fg
ab9

Script

sed -En '/^[^[:digit:]]*[[:digit:]]{1}[^[:digit:]]*$/p' filename

Output

a7b
2ab
9
abcfg9
9fg
ab9
sjsam
  • 21,411
  • 5
  • 55
  • 102
0

sed only supports BRE and ERE, but you can enable PCRE with grep -P:

% printf 'a77\na7b\n2ab\n82\n' | grep -P '(?<!\d)\d(?!\d)'
a7b
2ab

grep will as demonstrated print matched lines, but have an option to print the match only:

% printf 'a77\na7b\n2ab\n82\n' | grep -oP '(?<!\d)\d(?!\d)'
7
2
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
0

To do what you show in the Example in your question is:

$ sed -r 's/(^|[^0-9])1([^0-9]|$)/\1@\2/g' file
@ 2 3 4 5 11 @
agdse@tg@xw
6 97 45 12

but that only works because you didn't have 1 1 in your data. If you did you'd need 2 passes:

$ echo '1 1' | sed -r 's/(^|[^0-9])[0-9]([^0-9]|$)/\1@\2/g'
@ 1

$ echo '1 1' | sed -r 's/(^|[^0-9])[0-9]([^0-9]|$)/\1@\2/g; s/(^|[^0-9])[0-9]([^0-9]|$)/\1@\2/g'
@ @

and if you wanted to do that for any single digit it would be:

$ sed -r 's/(^|[^0-9])[0-9]([^0-9]|$)/\1@\2/g; s/(^|[^0-9])[0-9]([^0-9]|$)/\1@\2/g' file
@ @ @ @ @ 11 @
agdse@tg@xw
@ 97 45 12
Ed Morton
  • 188,023
  • 17
  • 78
  • 185