web-dev-qa-db-ja.com

並べ替えますが、ヘッダー行を上部に保持します

最初に一連の列ヘッダーである1行を生成し、次に一連のデータ行を生成するプログラムから出力を取得しています。この出力のさまざまな列を切り取り、さまざまな列に従って並べ替えて表示したいと思います。ヘッダーがなければ、sortへの-kオプションとcutまたはawkを使用して列のサブセットを表示することで、切り取りと並べ替えを簡単に実行できます。ただし、このソート方法では、列ヘッダーが残りの出力行と混合されます。ヘッダーを上部に配置する簡単な方法はありますか?

63
jonderry

アンディのアイデアを盗み、それを機能させて使いやすくします。

# print the header (the first line of input)
# and then run the specified command on the body (the rest of the input)
# use it in a pipeline, e.g. ps | body grep somepattern
body() {
    IFS= read -r header
    printf '%s\n' "$header"
    "$@"
}

今私はできる:

$ ps -o pid,comm | body sort -k2
  PID COMMAND
24759 bash
31276 bash
31032 less
31177 less
31020 man
31167 man
...

$ ps -o pid,comm | body grep less
  PID COMMAND
31032 less
31177 less
66
Mikel

あなたはbashでこのようにヘッダーを上部に保つことができます:

command | (read -r; printf "%s\n" "$REPLY"; sort)

または、Perlでそれを行います。

command | Perl -e 'print scalar (<>); print sort { ... } <>'
41
Andy

私は Nice awkバージョン を見つけましたが、スクリプトでうまく機能します。

awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'
30
Michael Kuhn

ハックだが効果的:先頭に0すべてのヘッダー行および1をソートする前に他のすべての行に。ソート後に接頭辞を取り除きます。

… |
awk '{print (NR <= 2 ? "0 " : "1 ") $0}' |
sort -k 1 -k… |
cut -b 3-

これは、出力をパイプ処理してすべてを並べ替えることができますが、最初の行を先頭に保つ、いくつかの魔法のPerl行ノイズです:Perl -e 'print scalar <>, sort <>;'

4

command | {head -1; sort; }ソリューションであり、-それは本当にねじ込まれている --headがパイプから複数の行を読み取り、最初の行だけを出力することを確認できます。したがって、残りの出力、つまりheadは読み取られなかったsort--に渡され、残りは2行目からの出力の!

その結果、コマンド出力の最初にあった行(および1行の部分的な行!)が欠落しています(最初の行がまだ残っている場合を除く)-wc上記のパイプラインの最後-ただし、これを知らなければ、追跡するのは非常に困難です。解決する前に、出力に部分的な行(最初の100バイト程度が途切れる)があった理由を解明するために、少なくとも20分間費やしました。

私がやったことは美しく機能し、コマンドを2回実行する必要はありませんでした。

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile
sed 1d $myfile | sort

rm $myfile

出力をファイルに入れる必要がある場合は、これを次のように変更できます。

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile > outputfile
sed 1d $myfile | sort >> outputfile

rm $myfile
2
Wildcard

これが一番簡単だと思います。

ps -ef | ( head -n 1 ; sort )

またはこれはサブシェルを作成しないため、おそらくより高速です

ps -ef | { head -n 1 ; sort ; }

その他のクールな用途

ヘッダー行の後の行をシャッフルする

cat file.txt |  ( head -n 1 ; shuf )

ヘッダー行の後の行を反転

cat file.txt |  ( head -n 1 ; tac )
1
user2449151
command | head -1; command | tail -n +2 | sort
0
Sarva

コマンドwの解決策を探してここに来ました。このコマンドは、誰がログインしていて、何をしているかの詳細を表示します。

ソートされた結果を表示するために、ヘッダーを最上部に保って(ヘッダーは2行あります)、次のように決めました。

w | head -n 2; w | tail -n +3 | sort

明らかにこれはコマンドwを2回実行するため、すべての状況に適しているとは限りません。しかし、その利点のために、覚えることはかなり簡単です。

tail -n +3は、「3番目以降のすべての行を表示する」を意味することに注意してください(詳細については、man tailを参照してください)。

0
Robert

シンプルでわかりやすい!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd ---> 'n'は行番号を指定し、 'd'は削除を表します。
0
Jatsui