2

In the UPPER.txt file, I need to substitute APPLE and ORANGE with non-capital apple and orange. I also need to keep the old file UPPER.txt as it was, and a generate a new file lower.txt. I am using the following commands:

sed 's/APPLE/apple/g' UPPER.txt > lower.txt
sed 's/ORANGE/orange/g' UPPER.txt > lower.txt

But the problem is that after I run the above command UPPER.txt and lower.txt become the same containing non-capital items. I want the UPPER.txt to remain as it was originally.

How can I keep a backup of the original file after using sed? Since I want to use this command in C++ using system(command) to operate on the files, I would like all the commands to be written in one line then I can pass it as string to system command.

14
  • 1
    what you are describing is not the expected behaviour. By default sed does not overwrite the original file; it writes to stdout (hence the result can be redirected using the shell operator > as you showed). Are you showing the exact commands used in your question?
    – Zanna
    Apr 21, 2018 at 14:58
  • 1
    @SebastianStark if that were so, the redirection would create an empty file, because sed -i doesn't print anything to stdout
    – Zanna
    Apr 21, 2018 at 15:15
  • 3
    The second command overwrites lowercase.txt and undoes the APPLE change from the first command. You need to chain them.
    – PerlDuck
    Apr 21, 2018 at 15:34
  • 1
    @Sepideha Please edit to add the text of UPPECASE.txt and lowercase.txt before and after running each sed command. If they're long, you can make a shorter input file and use that. (You needn't call your input file UPPECASE.txt, but either way, please do say explicitly what it is called.) Please also run ls -l UPPECASE.txt lowercase.txt and include the full output in your question. Although it would be strange to have created an alias, function, or alternate external command to make in-place changes when you run sed without -i, please also show the output of type -a sed. Apr 21, 2018 at 15:36
  • 2
    @GeorgeUdosen I'm not sure sed is broken here. The recent edit suggests the problem was what PerlDuck said about the second command undoing the effects of the first. I admit that's inconsistent with some of what the question says, but I still think it's the most likely explanation, based on the information available so far. Sepideha: Is that what you meant when you said the input and output files "become the same containing non-capital items"? Apr 21, 2018 at 17:16

2 Answers 2

4

I think you have got some misunderstandings.

The sed command only outputs the result in bash. It has nothing to do with original file. The > operator only writes the result to a file.

However, if you want, there is option -i which is able to edit the original file. With -i option comes backup suffix (optional).

$ cat UPPERCASE.txt 
APPLE
$ sed 's/APPLE/apple/g' UPPERCASE.txt
apple
$ sed 's/APPLE/apple/g' UPPERCASE.txt > lowercase.txt
$ cat UPPERCASE.txt 
APPLE
$ cat lowercase.txt 
apple
$ sed 's/APPLE/apple/g' -i[BACKUP] UPPERCASE.txt 
$ cat UPPERCASE.txt 
apple
$ ls
UPPERCASE.txt UPPERCASE.txt[BACKUP] lowercase.txt

Here, the [BACKUP] file is the original file.

1
  • @Zanna, I understood. Owing to this, In the first and second paragraph I wrote this is misunderstanding. And then I wrote if you want as an alternative.
    – Olimjon
    Apr 21, 2018 at 15:12
3

The command you mentioned sed 's/APPLE/apple/g' UPPER.txt > lower.txt shouldn't overwrite the original UPPER.txt, because sed's default behavior is to write to lower.txt. There's something else you've done that may have overwritten the original file. sed doesn't touch the original file unless you provide -i flag. For your purposes, I'd suggest first making a backup of the original file, aka just copy it.

On a side note, please be aware that system() call is kinda evil and shouldn't be used,

6
  • Thanks for the answer and warning about system(). Which one is more efficient in terms of runtime and memory? 1)first making a backup and running sed- or 2) my solution in EDIT section: running sed and deleting the temp file?
    – sepideha
    Apr 21, 2018 at 19:22
  • @Sepideha Your solution uses 3 commands. In shell, I would do sed 's/ORANGE/orrange/g; s/APPLE/apple/g' UPPER.txt > lower.txt. This is just one command, one single process, and redirects shell output to another file. UPPER.txt won't be touched. You of course can do backup as simply as copying the file, that's two commands: cp UPPER.txt UPPER.bak; sed 's/ORANGE/orrange/g; s/APPLE/apple/g' UPPER.txt > lower.txt. But if we're going to avoid system(), then ideal solution would be to capture output from C++ and output to new file (i.e., avoid shell and > operator). Apr 21, 2018 at 19:29
  • @ Sergiy Kolodyazhnyy Thanks for suggesting one-command to do all the job! great help. I am not sure how to avoid system() in this case. You mean first opening UPPER.txt file using c++ ifstream and after processing the text, useing ofstream to write on lower.txt file/buffer?
    – sepideha
    Apr 21, 2018 at 19:47
  • @Sepideha Yep, that. You can use popen to avoid system See this example with running a subprocess via popen and capturing output :stackoverflow.com/a/44611186/3701431 Apr 21, 2018 at 21:04
  • 1
    @PerlDuck Yep, that's the smartest route. OP will learn that eventually, one step at a time. Apr 22, 2018 at 8:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .