ファイルの最初と最後を表示するためのBashメソッド


8

キューベースのクラスターでは、保留中のジョブのキューは、コマンドなどから表示されますshowqueue

コマンドは、列など、名前などの適切なデータのリストを返しますが、列/データは質問には関係ありません。

私は時々のwatchようwatch showqueueにユーティリティを使用するのが好きです(エイリアスを使用alias watch="watch "して、コマンドのエイリアス展開を強制的に監視します)。最初の数行に重要なデータ(実行中のジョブ)があり、次に保留中のジョブなどがあり、最後にいくつかの重要な要約があります。

ただし、showqueueの出力が画面から消える場合があります(信じられないほど、私は知っています)。理想的には、ファイルの最初と最後を同時に表示できる方法が欲しいです。

私がこれまでに持っている最高のものは:showqueue > file; head -n 20 file > file2; echo "..." >> file2 ; tail -n 20 file >> file2; cat file2、そしてwatchそのエイリアスで使用することです。

誰かがもう少し柔軟な、または単一のユーティリティを知っていますか?私の解決策は、「...」の改行を複数行にするためのbashループで少し厄介になっています。ターミナルウィンドウのサイズを変更することはまったく適応されていません。

助言がありますか?


重複として閉じ、しかし、質問だけの共有の類似点(鉱山はmoreコマンドについてです、私が学んだ、およびファイルではなく)、ここで答えが表示されませんでしたが、どうしてもと言うならば
MadisonCooper

2
けっこうだ。再開しました。承諾した回答は、コマンドの最初の数行と最後の数行を表示するためのコマンドでの私の回答で述べたように、大きな出力に対してのみ機能することに注意してください(seq 30 | (head && tail)たとえば、試してください)。
ステファンChazelas

2
私はその答えを意味しました。別のQ&Aが(参照、それと合併したため、Q&Aは私の2つの答えを持っていることを質問履歴を
ステファンChazelasを

回答:


14

次のようなことをするつもりですか?ヘッドとテールの両方からの出力を表示します。

$ showqueue | (head && tail)

6
の一部の実装でheadは、10行を超える読み取りを行い、何もtail読み取ることができません。ユーティリティはそれを行うことを想定しておらず、GNUツールはこの点で適切に動作すると私は信じています。head; echo '...'; tailそこにもドットを取得するために使用します。
クサラナンダ

ええ、@ Kusalanandaのコメントと組み合わせると、私のソリューションよりもはるかに簡潔です。今のところ正しいとマークします!ありがとう。
MadisonCooper

4
@Kusalananda、いや、私のシステムでは、GNUヘッド(coreutils 8.26)は8192バイトのブロックを読み取ります。それはないしようと戻って追求することが、明らかにパイプの場合にはできません。とにかく、本当にhead読み過ぎないための要件は本当にありますか?(Macでも同じですが、ブロックで読むようです)
ilkkachu

2
@ilkkachuそうです、十分に長い出力でもテール部分が時々空白になることがあります(head -n 35を使用しているのでわかっていますが、それでいっぱいです)。必要に応じて更新のための秒。
-MadisonCooper

3
@ Kusalananda、POSIXでは、入力がシークできず、ほとんどの実装がそうである場合に、実装でそれを行うことができます。これを行わないと、一度に1バイトを読み取ることになるため、非常に非効率的です(または、サポートされているパイプにデータを戻すと、さまざまな種類の問題が発生します)。head10番目の改行を超えて読み取ることを避けるために一度に1バイトを読み取る唯一の実装は、ksh93のhead組み込みです。
ステファンChazelas

2

あなたと同じアプローチを使用し、一時ファイルを使用しますが、少し短くします:

showqueue >/tmp/q.out; head -n 20 /tmp/q.out; echo '...'; tail -n 20 /tmp/q.out

これは、別の回答で説明されているのと同じ問題に悩まされることはありませんが、出力が40行より短い場合、同じ行が2回表示される可能性あります。


+1同じ解決策を考えていましたが、tee出力を直接head入力するためにを使用し、保存された出力のみを使用するというわずかなバリエーションがありますtail
ジョー

2

先頭と末尾から表示される任意の数の行のawkソリューション(n=3量を設定するために変更):

$ seq 99999 | awk -v n=3 'NR <= n; NR > n { a[NR] = $0; delete a[NR-n]; } 
     END { print "..."; for (i = NR-n+1; i <= NR; i++) if (i in a) print a[i]; }'
1
2
3
...
99997
99998
99999

書かれているように、入力が行より短い場合でも、頭と尾の部分は重なりません2*n

一部のawk実装でfor (x in a) print a[x];は、ENDパーツでの使用も機能します。ただし、一般に、配列エントリが正しい順序で返されるとは限りません。たとえば、mawkでは返されません。


もしはm、ファイル内の行数、及びあるm < 2n印刷され、2n - m空行を。こちらもご覧ください ;-)。GNU awkでのみfor (x in a)順番に反復します。それでも機能すると思われる場合は、10より大きい値でテストしてください。mawk
モスビー

@mosvy、おお、おっと、気づかx in aなかったことを再確認するのを忘れていました。直しました、ありがとう。ステファンがリンクされている質問には、別のawk回答もあります。私はモジュロトリックが好きです!
ilkkachu

0

単純なawkスクリプトを使用できます。そこに追加されたサークルバッファーn = 3は最後の3行用です

awk 'NR<=n {print $0} { A[NR%n]=$0 } END { for (i=1; i<=n; ++i) if (NR+i>2*n)print A[(NR+i)%n] }' n=3 < <( seq 10 )

更新後は、もう簡単ではありませんが、


1
これは最初と最後の行のみを表示します。それ以上のものを表示するには、(または何かに)変更NR==1NR <= 10て、後でENDブロックに出力する(循環?)バッファーに行を収集する必要があります。
クサラナンダ

はい、更新させてください
Abdurrahim

これにより、行数が2 * n未満の場合、一部の行が2回印刷されます。
モスビー

:)了解しました。次は何が見つかるのか気になります:D
アブドゥルヒム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.