I have two unsorted lists of words, and I want to produce a new list excluding the words featuring some selected characters, and in order. I tried the following command:

 cat roa7.lst gr7.usl | sed -e 's/\s/\n/g' | sed -n 's/[^hlrw]/&/p' | sort -u | less -N

However, the last sed command, which tries to exclude the lines containing the set of characters [hlrw] fails to exclude these words. Somehow I'm missing the pragmatics of the caret within the delimiters. How can I fix this pipe?

  • I tried to use /[^hlrw]/p; can't figure out why this is not equivalent to /[hlrw]/!p though.
    – jarnosz
    Aug 24, 2021 at 1:39
  • fair enough: i misread the man page. shall go as community answer.
    – jarnosz
    Aug 24, 2021 at 4:45
  • to the original commenter: please, collect your comments under an answer, so that I may upvote and accept it.
    – jarnosz
    Aug 24, 2021 at 22:08
  • 1
    When asking questions on text-processing, please be sure to always include a testable example, i.e. (possibly anonymized) example input along with the desired output, and any further information on the structure and formatting of the input file. That way, contributors can verify proposed solutions before posting them as answers.
    – AdminBee
    Aug 25, 2021 at 7:29

2 Answers 2


The right syntax for the last sed command is

sed -n '/[hlrw]/!p'


sed '/[hlrw]/d'

which are roughly equivalent. The corresponding awk program would be

awk '!/[hlrw]/'

The wrong command in the original example means "contains any character not in the set hlrw" (which is true, unless the line consists wholly of characters h,l,r,w or is empty) while the second one is "find the lines containing any character in the set hlrw", and then, do not print them; or "find the lines including the set hlrw", and delete them from the input.


Here, you don't need sed, though. You could just do:

grep -v '[hlrw]'

The first (non-standard) sed -e 's/\s/\n/g' could also be replaced with:

tr -s '[:space:]' '[\n*]'

which transliterates and squeezes all sequences of white spaces into a newline character.

That would actually justify the use of cat (which is not needed for sed, as sed can take filenames as arguments and read from them directly).

Thus, the alternative syntax would be

cat roa7.lst gr7.usl | tr -s '[:space:]' '[\n*]' | grep -v '[hlrw]' | sort -u | less -N

which avoids completely the use of sed.

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.