it-swarm-id.com

urutkan tetapi pertahankan baris tajuk di bagian atas

Saya mendapatkan output dari program yang pertama kali menghasilkan satu baris yang merupakan sekelompok tajuk kolom, dan kemudian sekelompok baris data. Saya ingin memotong berbagai kolom dari output ini dan melihatnya diurutkan berdasarkan berbagai kolom. Tanpa header, pemotongan dan pemilahan mudah dilakukan melalui -k pilihan ke sort bersama dengan cut atau awk untuk melihat subset dari kolom. Namun, metode penyortiran ini mencampur header kolom dengan sisa garis output. Apakah ada cara mudah untuk menjaga header di atas?

63
jonderry

Mencuri ide Andy dan menjadikannya fungsi agar lebih mudah digunakan:

# 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"
    "[email protected]"
}

Sekarang saya bisa melakukan:

$ 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

Anda dapat menjaga tajuk di bagian atas seperti ini dengan bash:

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

Atau lakukan dengan Perl:

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

Saya menemukan versi awk yang bagus yang bekerja dengan baik dalam skrip:

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

Meretas tetapi efektif: prepend 0 ke semua baris header dan 1 ke semua baris lain sebelum mengurutkan. Keluarkan awalan setelah pengurutan.

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

Inilah beberapa derau Perl Perl yang ajaib yang bisa Anda gunakan untuk menyortir segala sesuatunya, tetapi pertahankan baris pertama di atas: Perl -e 'print scalar <>, sort <>;'

4
Ryan C. Thompson

Saya mencoba command | {head -1; sort; } solusi dan dapat mengonfirmasi bahwa benar-benar mengacaukan segalanya --head membaca dalam beberapa baris dari pipa, kemudian mengeluarkan yang pertama. Jadi sisa output, yang head tidak membaca , diteruskan ke sort-- BUKAN sisanya dari output mulai dari baris 2!

Hasilnya adalah Anda kehilangan baris (dan satu baris parsial!) Yang ada di awal output perintah Anda (kecuali Anda masih memiliki baris pertama) - fakta yang mudah dikonfirmasi dengan menambahkan pipa ke wc pada akhir pipa di atas - tetapi itu sangat sulit dilacak jika Anda tidak tahu ini! Saya menghabiskan setidaknya 20 menit mencoba mencari tahu mengapa saya memiliki garis parsial (100 byte pertama atau lebih terputus) dalam output saya sebelum menyelesaikannya.

Apa yang akhirnya saya lakukan, yang bekerja dengan indah dan tidak perlu menjalankan perintah dua kali, adalah:

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

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

rm $myfile

Jika Anda perlu memasukkan output ke file, Anda dapat memodifikasi ini ke:

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

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

rm $myfile
2
Wildcard

Saya pikir ini paling mudah.

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

atau ini yang mungkin lebih cepat karena tidak membuat sub Shell

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

Penggunaan keren lainnya

garis acak setelah baris tajuk

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

garis terbalik setelah baris tajuk

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

Saya datang ke sini mencari solusi untuk perintah w. Perintah ini menunjukkan detail siapa yang masuk dan apa yang mereka lakukan.

Untuk menunjukkan hasil yang diurutkan, tetapi dengan header tetap di atas (ada 2 baris header), saya memutuskan:

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

Jelas ini menjalankan perintah w dua kali dan karenanya mungkin tidak cocok untuk semua situasi. Namun, untuk keuntungannya secara substansial lebih mudah diingat.

Perhatikan bahwa tail -n +3 berarti 'tampilkan semua baris dari tanggal 3 dan seterusnya' (lihat man tail untuk detail).

0
Robert

Sederhana dan mudah!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd ---> 'n' menentukan baris no., dan 'd' adalah singkatan dari delete.
0
Jatsui