2

I cannot get this, or many other combinations of this, to work:

sed -i '' '/@/!d' file.txt
sed -i '' '/\@/!d' file.txt
sed -n '/@/p' file.txt > newfile.tx

What am I missing?

file.txt:

1. Lorem ip@sum dolor sit amet, consectetur adipiscing elit.
2. Nunc eu justo quis diam tempus auctor.
3. Suspe@ndisse in nulla et tellus aliquet finibus.
4. Aliquam @quis diam in tortor euismod faucibus ac lobortis massa.
5. Aenean feugiat nibh lobortis maximus pharetra.
6. Sed pharetra nibh id est lacinia, non pharetra nisi molestie.

desired result after sed or awk or grep or ??? deleting all lines not containing an @:

1. Lorem ip@sum dolor sit amet, consectetur adipiscing elit.
3. Suspe@ndisse in nulla et tellus aliquet finibus.
4. Aliquam @quis diam in tortor euismod faucibus ac lobortis massa.

UPDATE

Turns out there were funny line endings that OS X didn't like. The following worked:

tr '\r' '\n' < file.txt | grep -F '@' > newfile.txt

Thanks to @TomFenech for pointing me in the right direction.

Ryan
  • 14,682
  • 32
  • 106
  • 179
  • 1
    Is it possible that we've run into an issue with DOS line endings here? Try running `dos2unix` on your file. – Tom Fenech May 05 '15 at 11:00
  • If you want to do it awkwardly though `sed '/^[^@]*$/d'` –  May 05 '15 at 11:01
  • 1
    May be also good to check if the commands without redirection nor `-i` work to you. What do you get in the stdout if for example you say `sed '/@/!d' file`? – fedorqui May 05 '15 at 11:07
  • @TomFenech -- you were on the right track indeed! The following worked: `cat file.txt | tr '\r' '\n' > newfile.txt` and then `sed -i '' '/@/!d' newfile.txt` – Ryan May 05 '15 at 11:09

3 Answers3

7

It seems like your real problem was with your line endings but I think the best solution would be to use grep with the -F switch:

grep -F '@' file.txt

This prints lines that match the fixed string @ (no need for a regular expression match here).

You can pipe the output of tr like this:

tr -d '\r' < file.txt | grep -F '@'

Here I am deleting the carriage returns, rather than replacing them with a newline. Assuming that your files contain DOS-style line endings \r\n, this prevents blank lines from being added to the file.

If your files only have carriage returns, then you can use this option to substitute them for newlines:

tr '\r' '\n' < file.txt | grep -F '@'
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
5

you can do:

grep '@' file 

or with sed

sed -i '/@/!d' file

Edit

so your problem is, you added a space between sed's -i and ''. With this space, sed (tested with gnu sed) won't think the later '' is for backup. Also if you had -i option, you don't need the redirection. It will always give you an empty file.

Kent
  • 189,393
  • 32
  • 233
  • 301
  • How does this differ from the OP's attempt? – Tom Fenech May 05 '15 at 10:53
  • @TomFenech If you meant the `sed` command, I don't have `''` after `-i` and I don't redirect to `newfile` they are differences,aren't they? – Kent May 05 '15 at 10:57
  • OP doesn't redirect except in the example you didn't use –  May 05 '15 at 11:03
  • @JID check his edit. He changed his original question. – Kent May 05 '15 at 11:04
  • @JID well it may not be seen any longer, but OP had written `sed -i '' '/@/!d' file.txt > newfile` in his question when I posted the answer. – Kent May 05 '15 at 11:05
  • You all are right, I was editing a bunch. Apologies. Turned out it was a line ending problem. – Ryan May 05 '15 at 11:12
  • OSX `sed` is BSD `sed` which differs from GNU `sed` in various ways including needing a space between the `-i` and `''`. Your `sed` command will work perfectly for GNU `sed` but not for OSX's. – terdon May 05 '15 at 11:29
  • @terdon I have 0 experience with apple OS. OP edited the question a lot after I posted the answer. at that time, no any sign is showing it is on OSx. – Kent May 05 '15 at 14:11
  • 1
    I did not mean my comment as a critique, these small differences between the sed implementations are a pain. I just wanted to point out the issue. – terdon May 05 '15 at 14:36
  • @terdon apart from the difference, personally I think gnu sed is more powerful. There are some gnu-specific extension/features are quite nice. – Kent May 05 '15 at 14:46
4

You can also say: hey, just print those lines containing @:

$ sed -n '/@/p' file
1. Lorem ip@sum dolor sit amet, consectetur adipiscing elit.
3. Suspe@ndisse in nulla et tellus aliquet finibus.
4. Aliquam @quis diam in tortor euismod faucibus ac lobortis massa.
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • How can I get this to print to a new file? For whatever reason `file > newfile` isn't working for me. – Ryan May 05 '15 at 10:56
  • Could this be a Mac OS issue? I cannot get this to work. – Ryan May 05 '15 at 11:00
  • @Ryan So you are in OS X? What Wintermute suggested should be the way, see [In-place edits with sed on OS X](http://stackoverflow.com/a/7573438/1983854). Note the space between `-i` and `''`. – fedorqui May 05 '15 at 11:02