複数行のファイルがあり、各行の先頭にタイムスタンプがあります。
[Thread-3] (21/09/12 06:17:38:672) logged message from code.....
だから私はいつもこのログファイルで確認することが2つあります。
- 最初の数行にはグローバル条件があり、開始時間も提供されます。
- 最後の数行には、終了ステータスとその他の情報が含まれています。
ファイルの最初の行と最後の行のみを表示できる、迅速で便利な単一のコマンドはありますか?
答え1
@rushは大きなファイルの場合はhead + tailを使用するのが正しいですが、小さいファイル(20行未満)の場合は一部の行を2回出力できます。
{ head; tail;} < /path/to/file
同様にうまく動作しますが、上記の問題はありません。
答え2
sed
または、awk
コマンドを使用して実行できます。ただし、sed
とにかくawk
ファイル全体を実行する必要があるため、速度が急速に低下します。速度に関しては、毎回tail
+を組み合わせるか、関数を生成することをお勧めしますhead
。入力がパイプの場合は機能しないという欠点がありますが、シェルがそれをサポートしている場合はプロセス置換を使用できます(以下の例を参照)。
first_last () {
head -n 10 -- "$1"
tail -n 10 -- "$1"
}
その後、次のように起動します。
first_last "/path/to/file_to_process"
プロセスの交換を続けます(bash、zsh、kshなどのシェルのみ)。
first_last <( command )
grep
PS「グローバル条件」が存在することを確認するために1つを追加することもできます。
答え3
このソリューションは、チャンク単位で読み取るときにあまりにも多くのデータを消費する可能性があり、パイプから検索できない場合はカーソルが範囲外になる可能性があるため、パイプ{ head; tail; }
(またはソケットや他の検索できないファイル)では機能しません。head
file そのtail
意味が選択されました。
したがって、シェルのように一度に1文字を読み取るツールを使用できますread
(ここでは、最初の行と最後の行の数を引数として取る関数を使用します)。
head_tail() {
n=0
while [ "$n" -lt "$1" ]; do
IFS= read -r line || { printf %s "$line"; break; }
printf '%s\n' "$line"
n=$(($n + 1))
done
tail -n "${2-$1}"
}
seq 100 | head_tail 5 10
seq 20 | head_tail 5
またはawkで実装してくださいtail
。たとえば、次のようになります。
head_tail() {
awk -v h="$1" -v t="${2-$1}" '
{l[NR%t]=$0}
NR<=h
END{
n=NR-t+1
if(n <= h) n = h+1
for (;n<=NR;n++) print l[n%t]
}'
}
そしてsed
:
head_tail() {
sed -e "1,${1}b" -e :1 -e "$(($1+${2-$1})),\$!{N;b1" -e '}' -e 'N;D'
}
(一部のsed
実装では、パターン空間のサイズに対する制限が低いため、末尾の行の値が大きいと失敗します。)
答え4
プロセス置換を使用すると、bash
次のことができます。
make_some_output | tee >(tail -n 2) >(head -n 2; cat >/dev/null) >/dev/null
行の順序は保証されていませんが、長さが8kBを超えるファイルの場合はそうです。この 8kB カットオフは読み取りバッファの一般的なサイズであり、| {head; tail;}
小さなファイルには適用されない理由に関連しています。
これはパイプラインをアクティブにcat >/dev/null
保つhead
ために必要です。それ以外の場合は、tee
早期終了が発生し、出力を取得してもtail
終了ではなく入力の中間のどこかで発生します。
最後に別の場所>/dev/null
に移動してみてはいかがでしょうか?次の場合:tail
|
make_some_output | tee >(head -n 2; cat >/dev/null) | tail -n 2 # doesn't work
head
tail
標準出力はコンソールの代わりにパイプに移動しますが、これは私たちが望むものではありません。