No sistema GNU, você pode usar sed
(a implementação do GNU):
sed -i -n '/YISHA/p' file1
O equivalente do FreeBSD ou OS / X:
sed -i '' -n '/YISHA/p' file1
ou usando sponge
de moreutils :
grep "YISHA" file1 | sponge file1
Eu tenho um arquivo de entrada e executo algum comando, mas quero que a saída seja salva com o mesmo nome que o arquivo de entrada.
Eu tentei abaixo do comando, mas isso torna o arquivo de saída em branco:
cat file1 | grep "YISHA" > file1
No sistema GNU, você pode usar sed
(a implementação do GNU):
sed -i -n '/YISHA/p' file1
O equivalente do FreeBSD ou OS / X:
sed -i '' -n '/YISHA/p' file1
ou usando sponge
de moreutils :
grep "YISHA" file1 | sponge file1
Ao remover dados, você pode escrever o arquivo em si e depois truncá-lo:
{
grep YISHA
perl -e 'truncate STDOUT, tell STDOUT'
} < file 1<> file
Claro que aqui você pode fazer tudo em perl
:
perl -ne 'print if /YISHA/; END{truncate STDOUT, tell STDOUT}' < file 1<> file
perl
também tem uma opção -i
para edição no local (aquela que o GNU sed
copiou):
perl -ni -e 'print if /YISHA/' file
Mas note que, como sed
, cria um novo arquivo com o mesmo nome, ele realmente não reescreve o arquivo no local , o que significa números de inode e outros atributos do arquivo poderia ser afetado no processo. Ele também quebrará links simbólicos.
Seu shell provavelmente fornecerá a você um arquivo temporário seguro mediante solicitação:
grep "YISHA" <<IN > file
$(cat file)
IN
Isso soltará linhas em branco do final de file
, embora (que não deve ser relevante, a menos que você seja grep
ping para linhas em branco) . Se isso for importante, apenas echo .
após cat
na substituição do comando e solte a última linha.
Outra opção disponível para você é dd
. Por exemplo:
seq 5000000 >/tmp/temp
-rw-r--r-- 1 mikeserv mikeserv 38888896 Mar 11 04:20 /tmp/temp
Apenas um arquivo fictício grande o suficiente para compensar qualquer buffer de tubo.
</tmp/temp grep 5\$ |
dd bs=4k of=/tmp/temp conv=notrunc,sync
Você pode ver que excedi o tamanho de qualquer possível buffer de tubulação:
949+1 records in
950+0 records out
3891200 bytes (3.9 MB) copied, 0.164471 s, 23.7 MB/s
Quando a conversão notrunc
é especificada, dd
não toca no arquivo de saída, exceto para escrever sobre o que lê. Com seek=
, você pode até colocar esses dados de entrada em outro deslocamento no arquivo, se você gostou. Mas ... o arquivo ainda precisa ser truncado. Você pode ver que dd
liberou seu último buffer de entrada: 949 + 1 registros foram lidos, mas 950 foram escritos - dd
sincronizou seu último bloco de entrada para o tamanho total de 4k com nulos (que é um tamanho de bloco geralmente razoável para escolher ao aceitar entrada canalizada de ferramentas que usam stdio - como grep
) .
Então ...
ls -l /tmp/temp; tail /tmp/temp
-rw-r--r-- 1 mikeserv mikeserv 38888896 Mar 11 04:22 /tmp/temp
4999991
4999992
4999993
4999994
4999995
4999996
4999997
4999998
4999999
5000000
Ainda é o mesmo arquivo para tudo além do que dd
escreveu.
Mas ...
dd if=/dev/null bs=4k seek=950 of=/tmp/temp
... podemos truncá-lo ao ponto em que dd
escreveu para ele e ...
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000153783 s, 0.0 kB/s
... parece que nada aconteceu, exceto que ...
ls -l /tmp/temp; tail /tmp/temp
-rw-r--r-- 1 mikeserv mikeserv 3891200 Mar 11 04:25 /tmp/temp
4999915
4999925
4999935
4999945
4999955
4999965
4999975
4999985
4999995
dd
reduz esse tempo. Na verdade, no entanto, há aquele último bloco parcial sync
ed na parte final do arquivo, então ...
tail /tmp/temp | wc -c
2383
... há um monte de nulos no final.