Saída a ser salva no arquivo com o mesmo nome do arquivo de entrada [duplicado]

5

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
    
por yisha 11.03.2015 / 09:43

3 respostas

8

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
    
por 11.03.2015 / 09:48
4

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.

    
por 11.03.2015 / 12:13
4

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.

    
por 11.03.2015 / 10:57

Tags