web-dev-qa-db-ja.com

オフセット付きLinuxヘッド/テール

LinuxにはHeadまたはTailを要求する方法がありますが、無視するレコードの追加オフセットがあります。

たとえば、ファイルexample.lstには次が含まれます。

row01
row02
row03
row04
row05

そして、head -n3 example.lst行1〜3は取得できますが、最初の行をスキップして行2〜4を取得するにはどうすればよいですか。

一部のコマンドには、検索結果内で望ましくない可能性のあるヘッダーがあるためです。例えば ​​du -h ~ --max-depth 1 | sort -rhは、ホームディレクトリ内のすべてのフォルダのディレクトリサイズを降順で並べ替えて返しますが、現在のディレクトリを結果セットの先頭に追加します(つまり、~)。

HeadおよびTailのマニュアルページにはオフセットパラメータがないように見えるため、必要な行を指定できるrangeコマンドのようなものがあるかもしれません。 range 2-10 か何か?

18
hash-bang

man tailから:

   -n, --lines=K
        output the last K lines, instead of the last 10; 
        or use -n +K to output lines starting with the Kth

したがって、... | tail -n +2 | head -n 3を使用して、2行目から3行を取得できます。

非ヘッド/テールメソッドには、sed -n "2,4p"およびawk "NR >= 2 && NR <= 4"が含まれます。

37
that other guy

2〜4(両方を含む)の間の行を取得するには、次を使用できます。

head -n4 example.lst | tail -n+2

または

head -n4 example.lst | tail -n3
4
Farahmand

すべてのユースケースをカバーしている唯一のソリューションであると思われるこのソリューションにたどり着くまでに長い時間がかかりました(これまで):

command | tee full.log | stdbuf -i0 -o0 -e0 awk -v offset=${MAX_LINES:-200} \
          '{
               if (NR <= offset) print;
               else {
                   a[NR] = $0;
                   delete a[NR-offset];
                   printf "." > "/dev/stderr"
                   }
           }
           END {
             print "" > "/dev/stderr";
             for(i=NR-offset+1 > offset ? NR-offset+1: offset+1 ;i<=NR;i++)
             { print a[i]}
           }'

機能リスト:

  • ヘッドのライブ出力(明らかにテールの出力は不可能です)
  • 外部ファイルを使用しない
  • stderrのプログレスバー、MAX_LINESの後の各行に1つのドット。長時間実行されるタスクに非常に役立ちます。
  • バッファリング(stdbuf)による誤ったログの順序の可能性を回避
0
sorin