Finding lines of specific size in files using sed

i am using sed to detect any lines that are not exactly 21. the following gives me the lines that ARE exactly 21. i want the opposite , i want the two lines that are not size 21 (shown in bold)

type a.a
000008050110010201NNN
000008060810010201NNN
21212000008070110010201NNN
000008080310010201NNN
000008090510010201NNN
000008050110010201NNN
000008060310010201NNN
000008070110010201NNN
SUMM0001583381


sed -n "/^.\{20,21\}$/p" a.a
000008050110010201NNN
000008060810010201NNN
000008080310010201NNN
000008090510010201NNN
000008050110010201NNN
000008060310010201NNN
000008070110010201NNN

I think that this might give you lines that are 20 OR 21 characters long, but I'm not certain. A quick test should prove that to you. How does your code run for you with this as the input:-

12345678901234567890
123456789012345678901
1234567890123456789012
12345678901234567890123

Usually the ! will negate a search, so sed -n "!/Hello world/p" might print the unmatched lines. Does that help?

As an alternate, grep can use a regular expression, so grep -E '^.{21}$' a.a would match a 21 character line and grep -Ev '^.{21}$' a.a should match the others

Given the behaviour of type, can I assume that this is an emulation rather than a Unix/Linux server?

I hope that this helps, but please show the output/errors and we can dig in further if I've got it wrong.

Kind regards,
Robin

no it didnt help .. if i try to use "!" i get unknown command :frowning:

sed -n '!/^.\{20,21\}$/p' a.a
sed: Unknown command

---------- Post updated at 12:54 PM ---------- Previous update was at 12:36 PM ----------

i just noticed that my original command is flawed too .. its failing in this particular scenario , notice its showing the line that is not 21 ?

I just need a sed command that will give me all lines that are not exactly 21 .

type a.a
000008050110010201NNN
000008060810010201NNN
21212000008070110010201NNN
000008080310010201NNN
000008090510010201NNN
000008050110010201NNN
000008060310010201NNN
00008070110010201NNN
SUMM0001583381

$ sed -n '/^.\{20,21\}$/p' a.a
000008050110010201NNN
000008060810010201NNN
000008080310010201NNN
000008090510010201NNN
000008050110010201NNN
000008060310010201NNN
00008070110010201NNN

sed -n '/^.\{21\}$/!p' a.a

thanks

is it possible to break out of sed on the first non match instead of looping through the whole large file ?

Yes simply narrow the range to \{21,21\} or shorter \{21\}
Alternative: delete the lines that are exactly 21 characters long

sed '/^.\{21,21\}$/d' a.a

The d command jumps to the next input cycle, so a following quit command is run only when nothing is deleted.

sed '/^.\{21,21\}$/d;q' a.a

This is much simpler than

sed -n '/^.\{21\}$/!{p;q;}' a.a