0

Delete the string except for the beginning of NM, how should it be written with sed

input_file

NF
NM_001708.2(OPN1SW)
NM_000374.5(UROD)
NM_000235.4(LIPA)
NM_021828.5(HPSE2)
HPSE2, EX8-9DEL
HPSE2, EX3DEL
NM_021828.5(HPSE2)

output_file

NM_001708.2(OPN1SW)
NM_000374.5(UROD)
NM_000235.4(LIPA)
NM_021828.5(HPSE2)
NM_021828.5(HPSE2)

this method not what i wanted, because ^ That means the beginning, also means the reverse Ask how to optimize,thanks

sed -r '/^[^NM]/d' input_file 

2 Answers 2

2
$ sed '/^NM/!d' input_file
NM_001708.2(OPN1SW)
NM_000374.5(UROD)
NM_000235.4(LIPA)
NM_021828.5(HPSE2)
NM_021828.5(HPSE2)

The ! negates the match, so this sed script deletes every line that doesn't begin with NM. From man sed (GNU version):

After the address (or address-range), and before the command, a ! may be inserted, which specifies that the command shall only be executed if the address (or address-range) does not match.

With /^NM/!d, /^NM/ is the address (lines beginning with "NM"), and the command is d (delete).


BTW, ^ in a regular expression only means negate (or reverse in your terminology) when it's the first character inside a bracket expression. Your [^NM] means "match all characters which aren't either N or M", not "everything which isn't N followed by M".

7
  • thankyou! I can understand and think of this method, but can my method above be optimized?
    – mrqiao001
    May 3 at 14:40
  • optimised in what way? this is about as fast as it gets - it's a simple loop over the entire input file: read a line, decide whether to delete it or not.
    – cas
    May 3 at 14:42
  • Modify only the expression inside the slash (/)
    – mrqiao001
    May 3 at 14:43
  • what? that makes no sense.
    – cas
    May 3 at 14:46
  • 1
    sed -n '/^NM/p' input_file is probably the most obvious other way. Instead of deleting lines not beginning with NM, it prints only the lines beginning with NM. sed's -n option only prints output when you explicitly tell it to (with the p command), the opposite of it's normal mode of operation.
    – cas
    May 3 at 15:08
1

If you are OK with other tools you can try with grep

grep -e '^NM' input_file

or with awk

awk '/^NM/{print}' input_file

By recommendation from comment you can use with awk:

awk '/^NM/' input_file
1
  • 1
    You dont need to write {print} in awk, that's the default action when a condition is true. All you need is awk '/^NM/' input_file. You don't need the -e with grep either, just grep '^NM' input_file.
    – Ed Morton
    May 5 at 0:38

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.