Dostávám výstup z programu, který nejprve vytvoří jeden řádek, který je banda záhlaví sloupců, a pak banda řádků dat. Chci oříznout různé sloupce tohoto výstupu a zobrazit je seřazené podle různých sloupců. Bez záhlaví lze řezání a třídění snadno provést pomocí -k
možnost sort
spolu s cut
nebo awk
pro zobrazení podmnožiny sloupců. Tento způsob třídění však mísí záhlaví sloupců se zbytkem výstupních řádků. Existuje snadný způsob, jak udržet záhlaví nahoře?
Krást Andyho myšlenku a dělat z ní funkci, takže je snazší použití:
# 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]"
}
Nyní mohu udělat:
$ 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
Záhlaví můžete ponechat nahoře takhle s bash:
command | (read -r; printf "%s\n" "$REPLY"; sort)
Nebo to udělejte s Perlem:
command | Perl -e 'print scalar (<>); print sort { ... } <>'
Našel jsem pěkná verze awk , která funguje pěkně ve skriptech:
awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'
Hackish, ale efektivní: prepend 0
na všechny řádky záhlaví a 1
na všechny ostatní řádky před tříděním. Odstraňte předponu po třídění.
… |
awk '{print (NR <= 2 ? "0 " : "1 ") $0}' |
sort -k 1 -k… |
cut -b 3-
Zde je několik kouzelných šumů Perlu, kterými můžete procházet svůj výstup a třídit vše, ale ponechat první řádek nahoře: Perl -e 'print scalar <>, sort <>;'
Zkusil jsem command | {head -1; sort; }
řešení a může potvrdit, že to opravdu věci zvětšuje --head
čte na více řádcích z potrubí, pak vydává pouze první. Takže zbytek výstupu, který head
nečetl , se předá do sort
-- NENÍ zbytek výstupu od řádku 2!
Výsledkem je, že vám chybí řádky (a jeden dílčí řádek!), Které byly na začátku výstupu příkazu (kromě toho, že stále máte první řádek) - skutečnost, kterou lze snadno potvrdit přidáním kanálu do wc
na konci výše uvedeného potrubí - ale to je mimořádně obtížné dohledat, pokud to nevíte! Než jsem to vyřešil, strávil jsem alespoň 20 minut zkoušením, proč jsem měl ve svém výstupu částečný řádek (prvních 100 bajtů nebo tak odříznutý).
To, co jsem nakonec udělal, které fungovalo krásně a nevyžadovalo spuštění příkazu dvakrát, bylo:
myfile=$(mktemp)
whatever command you want to run > $myfile
head -1 $myfile
sed 1d $myfile | sort
rm $myfile
Pokud potřebujete vložit výstup do souboru, můžete jej upravit takto:
myfile=$(mktemp)
whatever command you want to run > $myfile
head -1 $myfile > outputfile
sed 1d $myfile | sort >> outputfile
rm $myfile
Myslím, že je to nejjednodušší.
ps -ef | ( head -n 1 ; sort )
nebo to, co je možná rychlejší, protože nevytváří subshell
ps -ef | { head -n 1 ; sort ; }
Další cool použití
zamíchat řádky za řádek záhlaví
cat file.txt | ( head -n 1 ; shuf )
zpětné řádky za řádkem záhlaví
cat file.txt | ( head -n 1 ; tac )
command | head -1; command | tail -n +2 | sort
Přišel jsem sem hledat řešení pro příkaz w
. Tento příkaz zobrazuje podrobnosti o tom, kdo je přihlášen a co dělají.
Abych zobrazil výsledky tříděné, ale s hlavičkami udržovanými nahoře (jsou zde 2 řádky záhlaví), usadil jsem se na:
w | head -n 2; w | tail -n +3 | sort
Je zřejmé, že to spustí příkaz w
dvakrát, a proto nemusí být vhodný pro všechny situace. Nicméně, jeho výhoda je podstatně snazší si zapamatovat.
Všimněte si, že tail -n +3
znamená 'zobrazit všechny řádky od třetího roku' (viz man tail
pro detaily).
Jednoduché a přímočaré!
<command> | head -n 1; <command> | sed 1d | sort <....>