web-dev-qa-db-ja.com

STDOUTのn行目を取得するコマンド

STDOUTのn行目を取得できるbashコマンドはありますか?

つまり、これをとる何か

$ ls -l
-rw-r--r--@ 1 root  wheel my.txt
-rw-r--r--@ 1 root  wheel files.txt
-rw-r--r--@ 1 root  wheel here.txt

そして次のようなことをする

$ ls -l | magic-command 2
-rw-r--r--@ 1 root  wheel files.txt

再利用することを意図したスクリプトを作成する場合、これは悪い習慣になると思いますが、シェルで日々作業しているときは、このようにSTDOUTをフィルタリングできると便利です。

また、これは書くための半自明なコマンドであることを認識しています(STDOUTをバッファリングし、特定の行を返す)が、いくつかのstandardシェルがあるかどうかを知りたいこれを行うコマンドは、スクリプトを所定の場所にドロップしなくても使用できます。

180
Alan Storm

さまざまな目的でsedを使用する場合:

ls -l | sed -n 2p

必要な行が印刷されると入力の読み取りを停止するため、より効率的に見えるこの代替手段を使用すると、フィードプロセスでSIGPIPEが生成され、不要なエラーメッセージが生成される場合があります。

ls -l | sed -n -e '2{p;q}'

lsはSIGPIPEを取得するときに文句を言うコマンドではありませんが、通常は最初のものを使用するほど頻繁に(これは入力が簡単です)十分に見ました。

行の範囲の場合:

ls -l | sed -n 2,4p

いくつかの範囲の行の場合:

ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
295
ls -l | head -2 | tail -1
75
mob

ニースの頭/尾の方法に代わるもの:

ls -al | awk 'NR==2'

または

ls -al | sed -n '2p'
39
ChristopheD

sed1line から:

# print line number 52
sed -n '52p'                 # method 1
sed '52!d'                   # method 2
sed '52q;d'                  # method 3, efficient on large files

awk1line から:

# print line number 52
awk 'NR==52'
awk 'NR==52 {print;exit}'          # more efficient on large files
21
Mark Edgar

完全を期すために;-)

短いコード

find / | awk NR==3

短命

find / | awk 'NR==3 {print $0; exit}'

Awkを使用できます。

ls -l | awk 'NR==2'

更新

上記のコードは、off-by-oneエラーのために必要なものを取得できません:ls -lコマンドの最初の行はtotal行。そのために、次の修正されたコードが機能します。

ls -l | awk 'NR==3'
6
Hai Vu

このsedバージョンを試してください:

ls -l | sed '2 ! d'

「2行目以外の行をすべて削除する」と表示されます。

6

Perlは簡単に利用できますか?

$ Perl -n -e 'if ($. == 7) { print; exit(0); }'

明らかに、7の代わりに任意の数字を使用します。

4
catfood

別のポスターが提案した

ls -l | head -2 | tail -1

しかし、頭を尾にパイプすると、行Nまでのすべてが2回処理されるように見えます。

頭に尾を配管

ls -l | tail -n +2 | head -n1

より効率的でしょうか?

2
nobody

はい、最も効率的な方法は(すでにJonathan Lefflerが指摘したように)sedをprint&quitで使用することです:

set -o pipefail                        # cf. help set
time -p ls -l | sed -n -e '2{p;q;}'    # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}"            # cf. man bash | less -p 'PIPESTATUS'
0
mco

うーん

私の場合、sedは機能しませんでした。私が提案する:

「奇数」行1,3,5,7 ...の場合ls | awk '0 ==(NR + 1)%2'

「偶数」行の場合2,4,6,8 ls | awk '0 ==(NR)%2'

0
stan