Exibir linhas em branco pelo comando cat


11

Eu tenho uma lista de files.txt, abaixo:

-rw-rw-r-- 1 root dev 11 May 16 12:18 20_SumActive.txt  
-rw-rw-r-- 1 root dev 11 May 16 12:18 22_SumActive.txt  
-rw-rw-r-- 1 root dev  7 May 16 12:18 24_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 26_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 28_SumActive.txt  

Resultado:

kpgmeddev01> cat 2[0-8]_SumActive.txt   
Sum: 47760  
Sum: 72000  
Sum: 0

Como obter saída como abaixo:

Sum: 47760  
Sum: 72000  
Sum: 0  
[Blank]  
[Blank]  

Precisa de orientação.


Os arquivos já contêm mais de uma linha?
roaima 16/05/19

Não, apenas 1 linha
Fewong

1
Quando você escreveu [Blank], você quis dizer aqueles 7 caracteres ou pretendia indicar uma linha vazia?
roaima 17/05

1
Por não usar gato. Não se restrinja.
Ctrl-alt-delor 17/05/19

Respostas:


20

catnão pode gerar dados que não existem nos arquivos. Se um arquivo estiver vazio, ele nem terá um caractere de nova linha para fornecer uma linha vazia como saída.

Você pode garantir que os arquivos contenham pelo menos um único caractere de nova linha.

É assim que você usa o GNU awkpara garantir que (isso modifique os arquivos vazios):

awk 'ENDFILE { if (FNR == 0) printf("\n") >>FILENAME }' 2[0-8]_SumActive.txt   

O ENDFILEbloco será executado depois de terminar de ler qualquer um dos arquivos. Se FNRfor zero, nunca vimos nenhuma linha no arquivo, então inserimos uma única nova linha nele. O script continua com o próximo arquivo.

Você pode usar catcomo fez na pergunta.


Como alternativa, sem alterar os arquivos, use o GNU em awk vez de cat :

awk 'ENDFILE { if (FNR == 0) printf("\n") } 1' 2[0-8]_SumActive.txt

Isso faz o mesmo tipo de detecção de arquivos vazios como acima, mas imprime a nova linha na saída padrão e não no arquivo. O 1final pode ser substituído por { print }e fará com que todos os dados nos arquivos não vazios sejam gerados.


Como alternativa, um loop de shell (deve funcionar em qualquer shell POSIX):

for name in ./2[0-8]_SumActive.txt; do
    if [ -s "$name" ]; then
        cat "$name"
    else
        printf '\n'
    fi
done

O -steste será verdadeiro se o arquivo existir e tiver um tamanho maior que zero.


Se você deseja que a string literal [Blank]seja gerada para arquivos vazios, basta inserir essa string na frente \nnas chamadas printfacima (isso também funcionará no awkcódigo).


2
@Fewong Good! Se isso resolver seu problema, considere aceitar a resposta .
Kusalananda

@Fewong: Ou aceite outra resposta que o ajude ainda melhor - é uma boa prática dar uma chance a todo fuso horário, para que não haja pressa.
MSalters

@Fewong Definitivamente não tem pressa. Stephané também escreveu uma solução curta e compacta, o que parece promissor.
Kusalananda

@ Kusalananda, obrigado e eu testei funcionou.
Fewong

16

Com perl

perl -0777 -pe 's/\n?\z/\n/' 2[0-8]_SumActive.txt

O que adiciona um caractere de nova linha se estiver ausente no final, geraria uma linha vazia para arquivos vazios, mas também acrescentaria uma nova linha para arquivos não vazios que não possuem (e acabariam sendo concatenados em uma única linha com cat).


boa sugestão
erTugRul

13

(Não é exatamente isso que você pergunta, mas :) Nesse tipo de situação, prefiro usar head

$ head -z 2[0-8]_SumActive.txt
==> 21_SumActive.txt <==
Sum: 47760  
Sum: 72000  
Sum: 0  

==> 22_SumActive.txt <==

==> 25_SumActive.txt <==

==> 28_SumActive.txt <==

Normalmente é isso que você deseja. Se não, é fácil seddepois


12

Com xargse grepvocê pode tentar algo como:

$>ls | xargs -n1 sh -c 'grep "" $0 || echo "[Blank]"'
Sum: 47760
Sum: 72000
Sum: 0
[Blank]
[Blank]

4
Talvez não seja a solução mais rápida (criando um shell para cada arquivo), mas apenas uma que funcione até o momento, se você tiver milhões desses arquivos no diretório atual (sem usar expansões de shell e atingir o limite de ARGV).
Matija Nalis 17/05/19

1
@MatijaNalis: Muito verdade! Mas você realmente não se importaria com 5 arquivos.
FloHimself

6

Supondo que [Blank]você quer dizer linhas em branco literais, isso deve funcionar:

paste -s 2[0-8]_SumActive.txt

6

Você pode testar cada arquivo para verificar se o comprimento é zero antes de tentar exibir seu conteúdo:

for f in 2[0-8]_SumActive.txt;
do
    [[ -s "$f" ]] && awk 1 "$f" || echo '[Blank]'
done

Eu usei, em awk 1 "$f"vez de, cat "$f"porque awkgarante terminar a saída de um arquivo com uma nova linha.

Na sua pergunta, se você pretendeu que isso [blank]não devesse ser literal, mas apenas uma linha em branco, você pode implementá-lo usando o código acima e removendo '[Blank]'do final da echoinstrução.


5

Estou assumindo que seus arquivos 26_SumActive.txt e 28_SumActive.txt estão vazios e você precisa de linhas em branco ao exibir seu conteúdo

Para isso, você pode simplesmente percorrer sua lista de arquivos e classificar seu conteúdo. Se o arquivo estiver vazio, faça eco da linha em branco.

[ -s FILE ] Verdadeiro se FILE existir e tiver um tamanho maior que zero.

$ for i in $(ls 2[0-8]_SumActive.txt) ; do  cat $i;  if [ ! -s $i ]; then echo -e ""; fi; done
Sum: 47760  
Sum: 72000  
Sum: 0  
[ Blank Line]
[ Blank Line ]

1
Or if [ -s $i ]; then cat $i; else echo -e ""; fi;. Ainda +1 para um teste simples usando apenas a funcionalidade padrão do shell.
MSalters

2
Ou apenas cat "$i"; test -s "$i" || echo- não há necessidade de sinalizadores pesados ifou não portáteis echo.
Toby Speight

1
cat 2[0-8]_SumActive.txt -

where - permitirá que o gato leia da entrada padrão.

Então, depois de exibir o conteúdo de seus arquivos, o gato aguardará sua entrada. Você pode fazer a entrada desejada pressionando Enter para espaços em branco literais ou [Blank] se for o que deseja. Após cada entrada pressionada, digite, depois que todas as entradas forem feitas, pressione ^ D (Ctrl + D) e pronto.

PS: Para cada entrada, você obterá a saída respectiva.

cat 2[0-8]_SumActive.txt - 4[0-8]_SumActive.txt

Com isso, você poderá colocar espaços em branco ou qualquer outra coisa que desejar, entre duas sequências de saídas.


Nesta base, você também pode oferecer catuma solução e permitir que o OP atinja o que eles desejam.
roaima 17/05
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.