0

I made a script,

cat $FILE | sed -e "s/^abc.*$/efg/" > $FILE

However, The contents of $FILE results in empty. If the code is

cat $FILE | sed -e "s/^abc.*$/efg/" > another_file.txt

the another_file.txt holds the correct results. If someone knows what is wrong or has solution/suggestion, please let me know.

Thank you very much.

mora
  • 2,217
  • 4
  • 22
  • 32
  • 2
    The simple answer is that *you can't read from a file and redirect output to it at the same time.* The long answer is too much work to find... (feeling lazy.) – J. Allan Jul 09 '16 at 19:59
  • Thank you Jefre N. Simple answer is enough for me. I just use another_file.txt and copy it to $FILE in the next line. – mora Jul 09 '16 at 20:12
  • 1
    I believe you can find the 'long answer' in the comments below [this post](http://stackoverflow.com/a/6696881/6491853), in case you want to learn **why** it doesn't work. :D (Glad the short answer was enough, though. ;)) – J. Allan Jul 09 '16 at 20:16
  • Thank you Jefre N again. I make a summary from the post Jefre introduced above. – mora Jul 09 '16 at 21:05
  • 1
    Same file cannot be redirect itself. It is because redirection '>' has higher priority than other execution. It means before cat $FILE, $FILE is truncated by a process of '>'. As a result, the $FILE results in empty. Avoid using > $FILE but use | tee $FILE. – mora Jul 09 '16 at 21:07
  • while all of this is true, you're not following good scripting practices. Assuming a modern linux with a modern(ish) `sed`, your problem be reduced to `sed -i '/s/^abc.*$/efg/' "$FILE"`. Notes ; not need for `cat $FILE|`. Use `-i` to write file back to same name. Use sngle-quotes for sed scripts with `$,*` and other shell meta chars unless you're trying to include a shell variable like repl=xyz ; sed s'/abc.*$/'"$repl/"`. And use dbl-quotes around all stnd-usage of variables, i.e. `"$FILE"`. Good luck. – shellter Jul 10 '16 at 03:53

1 Answers1

1

No, you cannot. $FILE is created before the pipeline starts

Bruce K
  • 749
  • 5
  • 15
  • P.S. if you want to go overboard on fanciness. I wouldn't, but you can: txt="$(< $FILE)" sed -e "s/^abc.*$/efg/" <<<"$txt" > $FILE – Bruce K Jul 09 '16 at 22:43