Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a file in a command and redirect output to the same file without truncating it?

Tags:

redirect

bash

io

People also ask

Can we redirect the output of a command to a file and display at the same time?

Redirecting output to Multiple files and screen: If you want to redirect the screen output to multiple files, the only thing you have to do is add the file names at the end of the tee command.

How can you redirect the output of a command to a file?

To redirect the output of a command to a file, type the command, specify the > or the >> operator, and then provide the path to a file you want to the output redirected to. For example, the ls command lists the files and folders in the current directory.

How do you redirect the output of a command to a file in batch?

Use >filename. txt 2>&1 to merge Standard Output and Standard Error and redirect them together to a single file. Make sure you place the redirection "commands" in this order.


Use sponge for this kind of tasks. Its part of moreutils.

Try this command:

 grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | sponge file_name

You cannot do that because bash processes the redirections first, then executes the command. So by the time grep looks at file_name, it is already empty. You can use a temporary file though.

#!/bin/sh
tmpfile=$(mktemp)
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name > ${tmpfile}
cat ${tmpfile} > file_name
rm -f ${tmpfile}

like that, consider using mktemp to create the tmpfile but note that it's not POSIX.


Use sed instead:

sed -i '/seg[0-9]\{1,\}\.[0-9]\{1\}/d' file_name

try this simple one

grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | tee file_name

Your file will not be blank this time :) and your output is also printed to your terminal.


One liner alternative - set the content of the file as variable:

VAR=`cat file_name`; echo "$VAR"|grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' > file_name

You can't use redirection operator (> or >>) to the same file, because it has a higher precedence and it will create/truncate the file before the command is even invoked. To avoid that, you should use appropriate tools such as tee, sponge, sed -i or any other tool which can write results to the file (e.g. sort file -o file).

Basically redirecting input to the same original file doesn't make sense and you should use appropriate in-place editors for that, for example Ex editor (part of Vim):

ex '+g/seg[0-9]\{1,\}\.[0-9]\{1\}/d' -scwq file_name

where:

  • '+cmd'/-c - run any Ex/Vim command
  • g/pattern/d - remove lines matching a pattern using global (help :g)
  • -s - silent mode (man ex)
  • -c wq - execute :write and :quit commands

You may use sed to achieve the same (as already shown in other answers), however in-place (-i) is non-standard FreeBSD extension (may work differently between Unix/Linux) and basically it's a stream editor, not a file editor. See: Does Ex mode have any practical use?