Reputation: 8314
I've got a script that calls grep to process a text file. Currently I am doing something like this.
$ grep 'SomeRegEx' myfile.txt > myfile.txt.temp
$ mv myfile.txt.temp myfile.txt
I'm wondering if there is any way to do in-place processing, as in store the results to the same original file without having to create a temporary file and then replace the original with the temp file when processing is done.
Of course I welcome comments as to why this should or should not be done, but I'm mainly interested in whether it can be done. In this example I'm using grep
, but I'm interested about Unix tools in general. Thanks!
Upvotes: 39
Views: 30117
Reputation: 9
cat myfile.txt | grep 'sometext' > myfile.txt
This will find sometext in myfile.txt and save it back to myfile.txt, this will accomplish what you want. Not sure about regex, but it does work for text.
Upvotes: -3
Reputation: 7
Store in a variable and then assign it to the original file:
A=$(cat aux.log | grep 'Something') && echo "${A}" > aux.log
Upvotes: -1
Reputation: 526
sponge
(in moreutils
package in Debian/Ubuntu) reads input till EOF and writes it into file, so you can grep file and write it back to itself.
Like this:
grep 'pattern' file | sponge file
Upvotes: 38
Reputation: 166833
To edit file in-place using vim-way, try:
$ ex -s +'%!grep foo' -cxa myfile.txt
Alternatively use sed
or gawk
.
Upvotes: 1
Reputation: 78364
Most installations of sed
can do in-place editing, check the man page, you probably want the -i
flag.
Upvotes: 2
Reputation: 93795
Take a look at my slides "Field Guide To the Perl Command-Line Options" at http://petdance.com/perl/command-line-options.pdf for more ideas on what you can do in place with Perl.
Upvotes: -2
Reputation: 342949
Perl has the -i
switch, so does sed
and Ruby
sed -i.bak -n '/SomeRegex/p' file
ruby -i.bak -ne 'print if /SomeRegex/' file
But note that all it ever does is creating "temp" files at the back end which you think you don't see, that's all.
Other ways, besides grep
awk
awk '/someRegex/' file > t && mv t file
bash
while read -r line;do case "$line" in *someregex*) echo "$line";;esac;done <file > t && mv t file
Upvotes: 20
Reputation: 51316
In general, this can't be done. But Perl has the -i
switch:
perl -i -ne 'print if /SomeRegEx/' myfile.txt
Writing -i.bak
will cause the original to be saved in myfile.txt.bak
.
(Of course internally, Perl just does basically what you're already doing -- there's no special magic involved.)
Upvotes: 5
Reputation: 41769
No, in general it can't be done in Unix like this. You can only create/truncate (with >) or append to a file (with >>). Once truncated, the old contents would be lost.
Upvotes: 4