Como '' e '' funcionam?

9

Eu tentei rev um arquivo e depois canalizei para cat > same_file , mas ele estava se transformando em um arquivo em branco.

Enquanto eu tentei rev file.txt | cat > file2.txt && mv file.txt file2.txt; funcionou.

Até rev file.txt | cat >> file.txt; funcionou.

Mas quando tentei o rev file.txt | cat > file.txt , ele falhou.

    
por Vintux 11.01.2015 / 14:00

4 respostas

18

A coisa básica que você precisa entender neste caso entre as duas formas de redirecionamento (> e > >) é:

>

Redireciona e sobrescreve as informações para as quais foi apontado. Isso acontece ao receber qualquer informação através do pipe "|"

> >

Redireciona e concatena para as informações para as quais foi apontado. Isso acontece ao receber qualquer informação através do pipe "|"

Em ambos os casos, se o arquivo não existir, ele será criado. Apenas em "> >" A informação será concatenada se você a executar novamente no mesmo arquivo. Com ">" você simplesmente sobrescreveria tudo o que você fez na primeira execução.

Mas aqui está o acordo ao usar o mesmo arquivo de entrada que o arquivo de saída. Nesse caso em particular, se você usar ">" você estaria removendo as informações que a parte de "entrada" precisa analisar, já que o arquivo de saída seria "sobrescrevendo-a". Então, em:

rev file.txt | cat > file.txt

O que está acontecendo na "explicação da câmera lenta" é:

  1. rev se prepara para reverter o conteúdo de file.txt e enviá-lo para o canal
  2. Enquanto rev está enviando as informações para o pipe, o pipe transmite diretamente para cat .
  3. Enquanto cat está recebendo as informações, elas serão aplicadas automaticamente ao file.txt definido com.
  4. A palavra-chave aqui é "while", porque tudo está acontecendo ao mesmo tempo. Por favor, veja os excelentes comentários abaixo por Emil para ter uma compreensão mais profunda sobre esta parte.
  5. cat não esperará que rev canalize todo o arquivo. Ele simplesmente iniciará no minuto em que a primeira parte das informações chegar, o que significa que, dependendo do símbolo que você usou, ele abrirá uma conexão com file.txt .
  6. Nesse caso, como você usou o > em vez de > > , o shell truncará o arquivo de saída, o que significa que ele abrirá e limpará as informações de file.txt enquanto aguarda a chegada das novas informações. Com > > , ele abriria uma conexão com file.txt e aguardaria novas informações na última linha detectada.
  7. Como as informações já foram limpas em file.txt com > , rev tentaria fazer seu trabalho e não receber nada porque cat excluiu tudo em preparação para as novas informações. / li>

Então, por que os outros trabalham depois de ler o acima. Por causa disso:

rev file.txt | cat > file2.txt && mv file.txt file2.txt

Aqui você está enviando para o cat que está enviando as informações para outro arquivo. Nesse caso, o arquivo de entrada processado file.txt não é igual ao arquivo de saída file2.txt . Depois disso, você está literalmente sobrescrevendo todo o file2.txt com file.txt , então todo o processo feito por cat foi excluído. Basicamente, toda a linha poderia ser simplificada como cp file.txt file2.txt porque está fazendo a mesma coisa, pois file2.txt no final perde o rev e é sobrescrito com o comando mv .

rev file.txt | cat >> file.txt

Nesse caso, você está concatenando as informações no mesmo arquivo. Por isso, é só abrir uma conexão com esse arquivo, mas não apagar as informações como visto com um único > . O resultado final deve ser a informação original mais a informação invertida.

    
por Luis Alvarado 11.01.2015 / 16:29
9

Quando o shell vê o redirecionamento, ele abre os arquivos relevantes primeiro, antes de executar qualquer um dos comandos envolvidos. Assim, quando você faz:

foo file.txt | bar > file.txt

O redirecionamento para file.txt faz com que seja truncado antes que foo seja executado e possa ler file.txt . Em uma nota lateral, é por isso que você não pode fazer:

sed 'blah' file.txt > file.txt

E por que sed tem uma opção de edição no local.

Por fim, fazendo:

.. | cat > file.txt

é um uso inútil de cat , especialmente se você está tentando ler de file.txt mais cedo em.

Se você quiser reverter um arquivo no local, não há atalhos . Você pode usar os truques sed ou awk com a edição no local.

    
por muru 11.01.2015 / 16:00
3

> é um redirecionador (operador) enviando a saída para outra coisa
(entrada do próximo comando, impressora ..)

No seu caso, a saída vai para um arquivo file.txt , se esse arquivo já existir, ele será sobrescrito, se não for criado.

>> é um operador de acréscimo, se file.txt já existir, a saída será anexada ao final do arquivo. se o arquivo não existir, ele será criado e a saída gravada no novo arquivo, igual a > (redirecionador).

    
por Ken Mollerup 11.01.2015 / 14:45
0

Você pode usar o Vim no modo Ex:

ex -sc '%!rev' -cx file.txt
  1. % seleciona todas as linhas

  2. ! comando de execução

  3. x salvar e fechar

por Steven Penny 16.04.2016 / 21:08