0

A very simple question (I think)

I´m learning to edit files with awk

I want to search all the liner from a file and delete all the lines with the word acetate

I have tried

awk 'match($0,"acetate") == 0 {print $0}' filename.txt > filename.txt

However this returns a empty txt file.

Any suggestion?

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
Francisco
  • 381
  • 3
  • 4
  • 13

5 Answers5

11

Try doing this :

awk '!/acetate/{print}' filename.txt > new_filename.txt &&
mv new_filename.txt filename.txt

or simply :

awk '!/acetate/' filename.txt > new_filename.txt &&
mv new_filename.txt filename.txt

You can't print and modify a file in the same time with awk. If you want' to do it in the same command, try using :

sed -i '/acetate/d' filename.txt

or for Mac Os X :

sed -i.'' '/acetate/d' filename.txt
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • thanks sputnick, sed might be the solution. However, I´m getting the following message: extra characters at the end of N command. any suggestion? – Francisco Jan 30 '13 at 23:20
  • 1
    See http://stackoverflow.com/questions/4247068/sed-command-failing-on-mac-but-works-on-linux – Gilles Quénot Jan 31 '13 at 00:06
  • 1
    please note that `sed -i` does not change the original file. It creates a new file and overwrites the original file, breaking hard links along the way. [reference](http://books.google.com/books?id=xBANKuFJWtUC&pg=PA243&lpg=PA243&dq=sed+-i+does+not+change+the+original+file&source=bl&ots=_qcIKN5EHZ&sig=mZhVOl0-aBZ03TfrdSA28PsxINE&hl=en&sa=X&ei=CmvEUrHQEaGj0QWllIC4CA&ved=0CDUQ6AEwAQ#v=onepage&q=sed%20-i%20does%20not%20change%20the%20original%20file&f=false) – Khaledvic Jan 01 '14 at 19:26
4

It looks like you are on UNIX. When you do this:

cmd file > file

where "cmd" is any UNIX command, you run the risk of "file" being overwritten by "> file" BEFORE it's read by "cmd file" so never do that.

Some tools like "sed" have options that allow "in-place" editing so the result of running that command on the input file is written back to that file. Most of them use temp files behind the scenes.

The safe, portable way to get the results of command written back to file is just to redirect the output to a tmp file and then move the temp file onto the original:

cmd file > tmp && mv tmp file

Safe, simple, and works for any command.

For your particular case of just looking for lines in a file that don't contain a particular word, the command you probably want is "grep" and you'd use it as:

grep -v acetate filename.txt > tmp && mv tmp filename.txt

For anything more complicated you'll probably want awk.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
2

sputnick has given a relatively complete answer, I add a grep way:

grep -v 'acetate' file > newfile
Kent
  • 189,393
  • 32
  • 233
  • 301
  • Thanks kent, if is not ask to much, what about if I want to include more words? – Francisco Jan 30 '13 at 23:44
  • e.g. you want to do with words foo, bar, baz. questions is you want to delete line with those three words in AND relation or OR? if OR, grep can do it simply. but AND, you need `grep | grep | grep -v` which is not so nice. better go with awk – Kent Jan 30 '13 at 23:47
2
perl -pi -e 'if(/acetate/){undef $_}' your_file

This will do an in-place replacement, which means your lines in the file with the string 'acetate' will be deleted automatically. Or you can also do:

perl -pi -e 'undef $_ if /acetate/' your_file

or

sed -i.bak '/acetate/d' temp
halfer
  • 19,824
  • 17
  • 99
  • 186
Vijay
  • 65,327
  • 90
  • 227
  • 319
1

Your command is ok, but you can't use the same file as input and output. You should use a pivot file and then move it:

awk 'match($0,"acetate") == 0 {print $0}' filename.txt > filename.tmp<br>
mv -f filename.tmp filename.txt
WoodChopper
  • 4,265
  • 6
  • 31
  • 55