cat出力から最初と最後の行を読み取る方法は?


64

テキストファイルがあります。タスク-後のファイルから最初と最後の行を取得する

$ cat file | grep -E "1|2|3|4" | commandtoprint

$ cat file
1
2
3
4
5

cat出力なしでこれが必要です(1と5のみ)。

~$ cat file | tee >(head -n 1) >(wc -l)
1
2
3
4
5
5
1

たぶんawkともっと短い解決策が存在する...


2番目の例でwc -lは、ファイルの最終行の出力とは関係ありません。
デビッドリチャービー14年

回答:


115

sedソリューション:

sed -e 1b -e '$!d' file

stdinif から読み取るときは、次のようになります(例:)ps -ef

ps -ef | sed -e 1b -e '$!d'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1931  1837  0 20:05 pts/0    00:00:00 sed -e 1b -e $!d

ヘッド&テールソリューション:

(head -n1 && tail -n1) <file

コマンドからデータが来ている場合(ps -ef):

ps -ef 2>&1 | (head -n1 && tail -n1)
UID        PID  PPID  C STIME TTY          TIME CMD
root      2068  1837  0 20:13 pts/0    00:00:00 -bash

awkソリューション:

awk 'NR==1; END{print}' file

また、次のパイプを使用した例ps -ef

ps -ef | awk 'NR==1; END{print}'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1935  1837  0 20:07 pts/0    00:00:00 awk NR==1; END{print}

1
ありがとうございました!(head -n1 file;tail -n1 file)最後のシンボルとして非常に大きなコマンドとパイプを使用することはできないため、これが最良の答えです。だから、| sed '1p;$!d'短い1。
dmgl 14年

あなたが私を理解していないなら、私の英語で申し訳ありません-それは私の問題です-それについて教えてください、私はあなたのためにより良いプレゼンテーションを準備します。
dmgl 14年

7
head && tail本当にあなたのために働きますか?seq 10 | (head -n1 && tail -n1)印刷1のみ。
グレンジャックマン14年

1
@DavidConradは、カオスが言ったことを詳しく説明するため-e 1bに、最初の行でsedスクリプトの最後に分岐します。この時点で、暗黙の「印刷」が行われます。入力が1行のみの場合、sedは終了します。それ以外の場合、最後を除くすべての行について、削除します。最後の行では、暗黙の「印刷」が再び発生します。
グレンジャックマン14年

1
@mikeserv:;-)機会があればチェックしてください。単一の行では、出力での重複を効果的に防ぎますが、複数行のワークケースでは、少なくともGNU sed4.2.2 では最後の行のみを保持します。乾杯。
Cbhihe

23

sed -n '1p;$p' file.txt file.txtの最初と最後の行を印刷します。


10
入力に1行しかない場合、2回印刷されることに注意してください。あなたがsed -e 1b -e '$!d'それを望まないなら、あなたは好むかもしれません。
ステファンシャゼル14年

10

面白い純粋なBash≥4の方法:

cb() { (($1-1>0)) && unset "ary[$1-1]"; }
mapfile -t -C cb -c 1 ary < file

その後、配列のary最初のフィールド(つまり、index 0)がの最初の行にfileなり、最後のフィールドがの最後の行になりfileます。コールバックcb(配列内のすべての行を丸lurみする場合はオプション)は、メモリが乱雑にならないようにすべての中間行を設定解除します。無料の副産物として、ファイル内の行数もあります(配列の最後のインデックス+ 1)。

デモ:

$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' {a..z})
$ declare -p ary
declare -a ary='([0]="a" [25]="z")'
$ # With only one line
$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' "only one line")
$ declare -p ary
declare -a ary='([0]="only one line")'
$ # With an empty file
$ mapfile -t -C cb -c 1 ary < <(:)
declare -a ary='()'

7

ではsed、あなたは可能性dのラインをelete場合、NOT1 ST 1 AND NOT$トン1。AND条件を結合するための条件と構成を(否定)
する!ために使用します。NOTX{Y..}X Y

cmd | sed '1!{$!d;}'

または、2ndからla $tまでの範囲を使用して、$lat行を除くその範囲内のすべての行を削除できます。

cmd | sed '2,${$!d;}'

6

Perlの使用:

$ seq 10 |  perl -ne 'print if 1..1 or eof'
1
10

上記の出力の最初の項目を印刷seq 10経由if 1..1しながら、or eofまた、最後の項目を印刷します。


3
これがどのように機能するか説明できますか?彼らが何をどのように行うかの説明なしに、そのようなワンライナーの答えを与えないでください。
テルドン

1
この質問は何をする必要が/etc abrtありyum.repos.dますか?
博士14年

@drs回答を編集して、「ls」をサンプル入力として使用しないようにしました。
ドルメン14年

1
@dolmen:/ etcへのすべての参照を抑制して編集を終了することをお勧めします。最初の編集後にそのようなものが追加されたと思いますが、答えはまったく意味をなさないため、すべて同じです。ただの提案。
-Cbhihe

4

猫なし:

$ cat file |tee >(head -n1) >(tail -n1) >/dev/null
1
5

または

$ (head -n1 file;tail -n1 file)
1
5

8
最初のものでは、行の順序は保証されません。
ステファンシャゼル14年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.