Existe uma maneira de fazer um “buffer completo de arquivos” dentro de uma cadeia de comandos canalizados?

1

Muitas vezes eu faço operações simples em um arquivo, por exemplo:

cat file1.txt|sed -r 's/^ *//'

para remover espaços no início da linha. Se eu quiser sobrescrever o arquivo, a única maneira que conheço é:

cat file1.txt|sed -r 's/^ *//' > file2.txt
mv file2.txt file1.txt

Isso é muito ennoying, porque eu tenho que verificar se file2.txt existe, porque eu tenho que escrever dois comandos em vez de um, e assim por diante.

Então eu pensei: existe uma maneira de fazer um buffer de arquivo completo dentro de uma cadeia de comandos canalizados? Então eu poderia escrever:

cat file1.txt| magicbuffercommand |sed -r 's/^ *//' > file1.txt

Este comando deve armazenar em buffer (até um máximo de bytes, é claro) e esperar por um EOF, e então deve começar a escrever para stdout.

Existe algo que possa fazer uma coisa dessas?

    
por d3k 04.12.2014 / 00:15

6 respostas

4

Você não precisa do cat . sed aceita felizmente o nome do arquivo como argumento:

sed 's/^ *//' <file>

Se você usar o GNU sed, poderá usar a opção -i ou --in-place para editar arquivo em vigor:

sed -i 's/^ *//' <file>

Para responder à pergunta, você pode obter o "buffer completo de arquivos" usando a ferramenta sponge do pacote moreutils . Usando sponge você pode fazer:

<command> <file> | sponge <file>  # or
<command1> < <file> | <command2> | sponge <file>

Usando seu exemplo sed , isso se torna:

sed 's/^ *//' <file> | sponge <file>
    
por 04.12.2014 / 00:42
1

Você já olhou para o comando do buffer do Linux? Isso utiliza um segmento de memória compartilhada do usuário para permitir basicamente leituras / gravações simultâneas. Suponho que poderia armazenar em buffer um arquivo inteiro se o segmento de memória compartilhada for grande o suficiente.

O comando buffer pode não ser instalado automaticamente, mas eu encontrei o programa em muitos dos repositórios em diferentes distribuições Linux. Na pior das hipóteses, você pode google e encontrar a fonte e compilar / vinculá-lo a si mesmo.

Eu usei o buffer para acelerar gravações em dispositivos mais lentos, como unidades de fita, e reduzi o tempo de transferência em cerca de 10-20%.

    
por 04.12.2014 / 00:20
0

Uma outra possibilidade é colocar todo o conteúdo de um arquivo em uma variável shell. Costumava haver um limite no tamanho, mas eu entendo que isso não é mais um problema. Contanto que você tenha a memória (é claro que exceder a memória física causaria a troca), você pode tentar o seguinte:

Por exemplo:

 varx='cat filename'
 echo "$varx" | sed ..... >$filename

Eu apenas mencionei isso caso você queira algo diferente de um comando sed.

    
por 04.12.2014 / 00:24
0

Você só precisa usar a opção -i de (GNU) , então

sed -i -r 's/^ *//' file_to_replace_in_place.txt 

e para o Os X:

sed -i.'' -r 's/^ *//' file_to_replace_in_place.txt 

Outra solução (mais genérica) é usar :

cat file | sed 's/^ *//' | tee file

você tem que cuidar de arquivos enormes, isso pode sair sem erro, nem mudar.

    
por 04.12.2014 / 00:16
0

Uso inútil do comando cat. Use o sed diretamente para imprimir o conteúdo ou use -i para fazer uma edição no local.

    
por 04.12.2014 / 00:26
0

Você pode usar o Vim no modo Ex:

ex -sc '%s/^ *//|x' file1.txt
  1. % seleciona todas as linhas

  2. s substituto

  3. x salvar e fechar

por 11.04.2016 / 05:12