catコマンドで空白行を表示する


11

以下にfiles.txtのリストがあります。

-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  

出力:

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

以下のように出力を取得する方法:

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

ガイダンスが必要です。


ファイルに複数の行が含まれていますか?
roaima

いいえ、1行のみ
2018年

1
ええと、あなたが書い[Blank]たとき、あなたはそれらの7文字を意味しましたか、それとも空の行を示すつもりでしたか?
ロアイマ

1
猫を使わないこと。あなたの自己を制約しないでください。
ctrl-alt-delor

回答:


20

catファイルに存在しないデータを出力することはできません。ファイルが空の場合、出力として空の行を提供する改行文字もありません。

ファイルに少なくとも1つの改行文字が含まれていることを確認できます。

これは、GNU awkを使用して次のことを確認する方法です(これにより、空のファイルが変更されます)。

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

ENDFILEブロックは、ファイルのいずれかを読み終えた後に実行されます。FNRが0の場合、ファイル内に行が1つもないため、改行を1つ挿入します。その後、スクリプトは次のファイルを続行します。

その後cat、質問で行ったように使用できます。


または、ファイルを変更せずawk に、 cat次の代わりに GNUを使用します。

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

これは上記と同じ種類の空のファイルの検出を行いますが、改行をファイルではなく標準出力に出力します。1最後には、置き換えることができる{ print }と非空のファイルのすべてのデータが出力されるようになります。


または、シェルループ(すべてのPOSIXシェルで動作するはずです):

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

-sファイルが存在し、ゼロよりもサイズの大きいを持っている場合、テストは真となります。


[Blank]空のファイルに対してリテラル文字列を出力したい場合\nは、printf上記の呼び出しの前にその文字列を挿入するだけです(これはawkコードでも機能します)。


2
@Fewong Good!これで問題が解決する場合は、回答を受け入れることを検討してください。
クサラナナンダ

@Fewong:または、さらに良い答えを受け入れる-すべてのタイムゾーンにチャンスを与えることは良い習慣であり、急いではありません。
MSalters

@Fewong間違いなく急いでいません。ステファネも短くコンパクトなソリューションを作成しました。これは有望に見えます。
クサラナナンダ

@Kusalananda、ありがとう、私はそれがうまくいくかテストした。
フェウォン

16

perl

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

末尾にない場合は改行文字が追加されるため、空のファイルの場合は空の行が出力されますが、空のファイルがない場合は改行が追加されます(1つの行にが連結されることになりますcat)。


良い提案
-erTugRul

13

(これはまさにあなたが尋ねるものではありませんが、:)このタイプの状況では、私は使用したいです 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 <==

通常、これはあなたが望むものです。そうでなければsed、後でそれは簡単です


12

xargsし、grepあなたのような何かを試すことができます:

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

4
おそらく最速の解決策(ファイルごとにシェルをフォークする)ではなく、現在のディレクトリに数百万のファイルがある場合に実際に機能する(シェル拡張を使用せず、ARGV制限に達する)1つだけです。
マティヤナリス

1
@MatijaNalis:非常に本当です!しかし、あなたは本当に5つのファイルを気にしません。
FloHimself

6

[Blank]あなたがリテラルの空白行を意味すると仮定すると、これはうまくいくはずです:

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

6

内容を表示する前に、各ファイルをテストして長さがゼロかどうかを確認できます。

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

ファイルの出力を改行で終了することが保証されるため、awk 1 "$f"代わりに使用しました。cat "$f"awk

あなたの質問では、それが[blank]リテラルではなく空白行であることを意図している場合は、上記のコードを使用してこれを実装し'[Blank]'echoステートメントの末尾から削除できます。


5

私はあなたのファイル26_SumActive.txtと28_SumActive.txtが空であり、その内容を表示するときに空白行が必要であると想定しています

この場合、ファイルのリストを反復処理して、その内容をcatし、ファイルが空の場合は空白行をエコーできます。

[ -s FILE ] FILEが存在し、サイズがゼロより大きい場合はtrue。

$ 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
またはif [ -s $i ]; then cat $i; else echo -e ""; fi;。それでも、標準のシェル機能だけを使用した単純なテストの場合は+1。
MSalters 2018年

2
または単にcat "$i"; test -s "$i" || echo-その扱いにくいifまたは移植できないechoフラグは必要ありません。
トビースパイト

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

どこ - 標準入力からの読み取りに猫を可能にします。

したがって、ファイルの内容を表示した後、猫はあなたの入力を待ちます。Enterキーを押してリテラルブランクを入力するか、[Blank]を押して必要な入力を行うことができます。各入力がEnterキーを押した後、すべての入力が行われたら^ D(Ctrl + D)を押すと完了です。

PS:各入力に対して、それぞれの出力が得られます。

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

これにより、出力の2つのシーケンスの間に、空白やその他の必要なものを置くことができます。


これに基づいcatて、ソリューションとして提供するだけでなく、OPが望むものを許可することもできます。
roaima
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.