O comando cat repassa um arquivo ou o conteúdo do arquivo?

2

Compare os seguintes comandos:

cat f.txt | grep "someText" 
grep "someText" f.txt

Ambos parecem funcionar. Mas a documentação do cat diz que o cat produz o conteúdo do arquivo em vez do nome do arquivo e o comando grep pega o nome do arquivo, mas não o conteúdo do arquivo (corrija-me se estiver errado), então por que o primeiro comando funciona? o conteúdo do arquivo, em vez do nome do arquivo.

Outra pergunta: os dois funcionam, mas por que alguém usaria a primeira linha em vez da segunda, a primeira é redundante?

    
por Kun 23.04.2016 / 17:50

2 respostas

7

No seu primeiro exemplo

cat f.txt | grep "someText" 

grep não recebe um argumento de nome de arquivo, apenas uma string para procurar. Nesse caso, grep lerá o texto para pesquisar a partir da entrada padrão. Nesse caso, essa entrada padrão é canalizada a partir da saída de cat f.txt , que gera o conteúdo do arquivo , não o nome do arquivo.
O que você também poderia ter feito para fazer grep ler a partir de stdin é usar:

< f.txt grep "someText"

Usar cat é muitas vezes redundante por si só (independente de grep ) e pode ser substituído pelo redirecionamento de entrada como acima. Eu sempre usaria o segundo formulário no seu exemplo, a menos que você tenha que fazer um pré-processamento na entrada.

    
por 23.04.2016 / 17:52
2

Existem dois motivos principais para usar cat como no seu primeiro exemplo:

  1. Como um marcador de lugar para algum outro comando ou um longo e complicado pipeline de comandos.

    por exemplo. se você estiver escrevendo um script ou uma linha para processar um arquivo enorme ou dados de uma consulta psql / mysql ou wget ou jq etc, salve (alguns) a entrada em um amostra de arquivo e use cat sample como entrada até obter o script ou o direito de uma linha. Em seguida, basta substituir o cat pelo comando ou pipeline real.

    Da mesma forma, é um lugar útil se o seu propósito é ensinar alguém sobre cachimbos.

    (Muitas pessoas chamam isso de Useless Use of Cat ou UUOC. Isso é em grande parte porque eles são presunçosos e gostam de usar seu conhecimento supostamente superior para derrotar os novatos em vez de ajudá-los a aprender - o terrível crime de usar cat que < é tão importante que não pode ser ignorado como se fosse apenas um detalhe trivial. o mundo acabaria, seria um cat astrophe.)

  2. Quando você não quer que um programa conheça o (s) nome (s) do (s) nome (s) do (s) arquivo (s) de entrada. por exemplo. cat * | grep ... é diferente de grep ... * .

    Isso não importa muito, mas quando isso acontece, pode importar muito.

    Para grep , você pode suprimir a listagem dos nomes de arquivos com -h , mas outros programas não têm essa opção - wc , por exemplo, sempre exibirá os nomes de arquivos e contagens por arquivo, mesmo que você não use não os quer.

    Você pode, claro, usar algo como wc * | tail -1 | awk '{print $1, $2, $3}' , mas isso não funciona se você estiver fazendo algo como find . -type f -exec wc {} + e a lista de nomes de arquivos gerados por find exceder o comprimento máximo da linha de comando do shell. Nesse caso, você obtém várias linhas 'totais' (e não há como distinguir entre uma linha total real e um arquivo com o nome 'total' na saída de wc ).

    find . -type f -exec cat {} + | wc produz apenas uma linha de saída (os totais), independentemente de quantos arquivos find encontrar, nenhum ou um ou muitos.

    ( wc precisa realmente das opções --totals-only e --no-totals .)

por 24.04.2016 / 02:42