I'm using sed on a command line to edit a file.
This works:
sed "1,/abc/d" file1.txt > file2.txtIt excises everything in file1.txt up to and including the abc.
But this doesn't:
sed "1,/abc-def/d" file1.txt > file2.txtBecause the hyphen is supposed to be a literal, so
I use an escape character:
sed "1,/abc\-def/d" file1.txt > file2.txt. But it doesn't work.seddoes not recognize it. The output file is empty.I try it with a wildcard character:
sed "1,/" file1.txt > file2.txt.I use brackets:
sed "1,/abc[-]def/d" file1.txt > file2.txt.I use a numerical literal:
sed "1,/abc\D2def/d" file1.txt > file2.txt.And, of course, I use every conceivable combination of escape characters under the sun.
But no matter what I do, sed will not recognize a literal hyphen. How does sed know what I'm trying to do so that it can refuse? Is this one of those quantum mechanical things, like it will only do it if i don't check the results? Talk about confusing...
[next day] ok i used a hex editor to verify that it is a hyphen, ascii x2D, it is a single character. And for fun i tried again with just a naked hyphen, no luck of course. and i checked the locale, too. It said United States English.
here's another fine example. this works: sed "1,/abc/d" file1.txt > file2.txt
but this don't: sed "1,/\"abc/d" file1.txt > file2.txt not even if i use an ascii code (\x22) for the double quote, sed WON'T match it, no matter what. I still have no theory except that sed is conscious and knows what i'm trying to do.
ok thanx Kamil your example sed "1,/abc-def/d" did work. so did this: sed "1,/abc\-def/d" and this: sed "1,/abc\x2Ddef/d"
and I'LL BE FUKED check this out. Using my own file1.txt this works: sed "1,/balance/d" file1.txt > file2.txt but THIS DOESN'T: sed "1,/\x22balance/d" file1.txt > file2.txt Here's the actual string in file1.txt: name="balance" how deep does the rabbit hole go? [\next day]
2 Answers
You are correct in that you need to escape the hyphen. The dash (or hyphen) is used to indicate a range, unless you escape it. With out the backslash, sed isn't interpreting the dash as a hyphen.
Looks to me like you are not properly escaping the hyphen. You need a back slash before the character to use as an escape character.sed "1,/abc\-def/d" file1.txt > file2.txt
This will properly escape the hyphen.
The dot is a wild card for any single character and will match more than you want. Consider this command:echo "abc def abc.def abc-def abc+def abc++def" | sed -e "s/"This will look for the character string 'abcdef' and replace it with a '+' (The 'g' means global and replace everything on the line.)+ + + + abc++def
Now, lets change the dot to an escaped hyphen:echo "abc def abc.def abc-def abc+def abc++def" | sed -e "s/abc\-def/+/g"The answer shows exactly what you want:abc def abc.def + abc+def abc++def
Note: In this example, I've put all of the entries on 1 line for clarity and added the 'g' parameter.
In your example, since you are working on lines, not words on each line, you don't need the 'g'
well the problem turned out to be in the file1.txt that i was using for input. A 28k text file comprised of 14 lines of text. The 14th line was over 13k long, so when i used
sed "1,/abc/d" file1.txt > file2.txtthe target string was in the middle of the file, but it was in the very last record. I misread the structure of the input file. Sed was doing it's job, excluding every line up to and including the target line. The output file, file2.txt, was empty and i didn't know why. Thanx to everyone for your help. i should say that the real problem was incompetence. i gave the local exorcist a fat tip and sent him on his way.