it-swarm.it

ordina ma mantieni la riga di intestazione in alto

Sto ottenendo output da un programma che dapprima produce una riga che è un gruppo di intestazioni di colonna, quindi un gruppo di righe di dati. Voglio tagliare varie colonne di questo output e visualizzarlo in base a varie colonne. Senza le intestazioni, il taglio e l'ordinamento sono facilmente realizzabili tramite il -k opzione su sort insieme a cut o awk per visualizzare un sottoinsieme delle colonne. Tuttavia, questo metodo di ordinamento mescola le intestazioni di colonna con il resto delle righe di output. C'è un modo semplice per mantenere le intestazioni in alto?

63
jonderry

Rubare l'idea di Andy e renderla una funzione in modo che sia più facile da usare:

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

Ora posso fare:

$ 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

Puoi mantenere l'intestazione in alto in questo modo con bash:

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

O fallo con Perl:

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

Ho trovato na versione di Awk Nice che funziona bene negli script:

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

Hackish ma efficace: anteponi 0 a tutte le righe di intestazione e 1 a tutte le altre righe prima dell'ordinamento. Rimuovi il prefisso dopo l'ordinamento.

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

Ecco alcuni rumori magici della linea Perl che puoi convogliare il tuo output per ordinare tutto ma mantenere la prima riga in alto: Perl -e 'print scalar <>, sort <>;'

4
Ryan C. Thompson

Ho provato il command | {head -1; sort; } soluzione e può confermare che rovina davvero le cose --head legge in più righe dalla pipe, quindi emette solo la prima. Quindi il resto dell'output, che head non ha letto , viene passato a sort-- NON il resto dell'uscita a partire dalla linea 2!

Il risultato è che mancano le righe (e una riga parziale!) Che erano all'inizio dell'output del comando (tranne che hai ancora la prima riga) - un fatto che è facile da confermare aggiungendo una pipe a wc alla fine della suddetta pipeline - ma è straordinariamente difficile da rintracciare se non lo sai! Ho impiegato almeno 20 minuti a cercare di capire perché avevo una linea parziale (i primi 100 byte circa) nell'output prima di risolverlo.

Quello che ho finito per fare, che ha funzionato magnificamente e non ha richiesto di eseguire il comando due volte, è stato:

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

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

rm $myfile

Se è necessario inserire l'output in un file, è possibile modificarlo in:

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

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

rm $myfile
2
Wildcard

Penso che sia più semplice.

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

o questo che è probabilmente più veloce in quanto non crea una Shell secondaria

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

Altri usi interessanti

riordina le righe dopo la riga di intestazione

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

righe inverse dopo la riga di intestazione

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

Sono venuto qui alla ricerca di una soluzione per il comando w. Questo comando mostra i dettagli di chi ha effettuato l'accesso e cosa stanno facendo.

Per mostrare i risultati ordinati, ma con le intestazioni mantenute in alto (ci sono 2 righe di intestazioni), ho optato per:

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

Ovviamente questo esegue il comando w due volte e quindi potrebbe non essere adatto a tutte le situazioni. Tuttavia, a suo vantaggio, è sostanzialmente più facile da ricordare.

Nota che il tail -n +3 significa "mostra tutte le righe dal terzo in poi" (vedi man tail per dettagli).

0
Robert

Semplice e diretto!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd ---> 'n' specifica il numero di riga e 'd' sta per cancellazione.
0
Jatsui