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シェルがあるかどうかを知りたいこれを行うコマンドは、スクリプトを所定の場所にドロップしなくても使用できます。
さまざまな目的で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'
ls -l | head -2 | tail -1
ニースの頭/尾の方法に代わるもの:
ls -al | awk 'NR==2'
または
ls -al | sed -n '2p'
完全を期すために;-)
短いコード
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'
このsed
バージョンを試してください:
ls -l | sed '2 ! d'
「2行目以外の行をすべて削除する」と表示されます。
Perlは簡単に利用できますか?
$ Perl -n -e 'if ($. == 7) { print; exit(0); }'
明らかに、7の代わりに任意の数字を使用します。
別のポスターが提案した
ls -l | head -2 | tail -1
しかし、頭を尾にパイプすると、行Nまでのすべてが2回処理されるように見えます。
頭に尾を配管
ls -l | tail -n +2 | head -n1
より効率的でしょうか?
はい、最も効率的な方法は(すでに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'
うーん
私の場合、sedは機能しませんでした。私が提案する:
「奇数」行1,3,5,7 ...の場合ls | awk '0 ==(NR + 1)%2'
「偶数」行の場合2,4,6,8 ls | awk '0 ==(NR)%2'