significa - ¿Hay alguna forma de ignorar las líneas de encabezado en UNIX?
que pasa cuando ignoras un mensaje de messenger (11)
Tengo un archivo de campo de ancho fijo que trato de ordenar usando la utilidad de ordenamiento UNIX (Cygwin, en mi caso).
El problema es que hay un encabezado de dos líneas en la parte superior del archivo que se ordena en la parte inferior del archivo (ya que cada línea de encabezado comienza con dos puntos).
¿Hay alguna manera de decir ordenar, ya sea "pasar las dos primeras líneas sin clasificar" o especificar un orden que ordene las líneas de dos puntos hasta la parte superior? Las líneas restantes siempre comienzan con un número de 6 dígitos (que en realidad es la clave I estoy clasificando) si eso ayuda.
Ejemplo:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00
debería ordenar a:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
Aquí hay una función de shell bash derivada de las otras respuestas. Maneja tanto archivos como pipas. El primer argumento es el nombre del archivo o ''-'' para stdin. Los argumentos restantes se pasan a sort. Un par de ejemplos:
$ hsort myfile.txt
$ head -n 100 myfile.txt | hsort -
$ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r
La función de shell:
hsort ()
{
if [ "$1" == "-h" ]; then
echo "Sort a file or standard input, treating the first line as a header.";
echo "The first argument is the file or ''-'' for standard input. Additional";
echo "arguments to sort follow the first argument, including other files.";
echo "File syntax : $ hsort file [sort-options] [file...]";
echo "STDIN syntax: $ hsort - [sort-options] [file...]";
return 0;
elif [ -f "$1" ]; then
local file=$1;
shift;
(head -n 1 $file && tail -n +2 $file | sort $*);
elif [ "$1" == "-" ]; then
shift;
(read -r; printf "%s/n" "$REPLY"; sort $*);
else
>&2 echo "Error. File not found: $1";
>&2 echo "Use either ''hsort <file> [sort-options]'' or ''hsort - [sort-options]''";
return 1 ;
fi
}
Aquí hay una versión que funciona en datos canalizados:
(read -r; printf "%s/n" "$REPLY"; sort)
Si su encabezado tiene varias líneas:
(for i in $(seq $HEADER_ROWS); do read -r; printf "%s/n" "$REPLY"; done; sort)
Esta solución es de here
Así que aquí hay una función bash donde los argumentos son exactamente como sort. Soporte de archivos y tuberías.
function skip_header_sort() {
if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
local file=${@: -1}
set -- "${@:1:$(($#-1))}"
fi
awk -vsargs="$*" ''NR<2{print; next}{print | "sort "sargs}'' $file
}
Cómo funciona. Esta línea verifica si hay al menos un argumento y si el último argumento es un archivo.
if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
Esto guarda el archivo en un argumento separado. Ya que estamos a punto de borrar el último argumento.
local file=${@: -1}
Aquí eliminamos el último argumento. Como no queremos pasarlo como un argumento de ordenación.
set -- "${@:1:$(($#-1))}"
Finalmente, hacemos la parte awk, pasando los argumentos (menos el último argumento si era el archivo) para ordenar awk. Esto fue sugerido originalmente por Dave y modificado para tomar argumentos de clasificación. Confiamos en que $file
estará vacío si estamos canalizando, por lo tanto, ignorado.
awk -vsargs="$*" ''NR<2{print; next}{print | "sort "sargs}'' $file
Ejemplo de uso con un archivo separado por comas.
$ cat /tmp/test
A,B,C
0,1,2
1,2,0
2,0,1
# SORT NUMERICALLY SECOND COLUMN
$ skip_header_sort -t, -nk2 /tmp/test
A,B,C
2,0,1
0,1,2
1,2,0
# SORT REVERSE NUMERICALLY THIRD COLUMN
$ cat /tmp/test | skip_header_sort -t, -nrk3
A,B,C
0,1,2
2,0,1
1,2,0
Con Python:
import sys
HEADER_ROWS=2
for _ in range(HEADER_ROWS):
sys.stdout.write(next(sys.stdin))
for row in sorted(sys.stdin):
sys.stdout.write(row)
Esto es lo mismo que Ian Sherbin, pero mi implementación es:
cut -d''|'' -f3,4,7 $arg1 | uniq > filetmp.tc
head -1 filetmp.tc > file.tc;
tail -n+2 filetmp.tc | sort -t"|" -k2,2 >> file.tc;
Puede usar tail -n +3 <file> | sort ...
tail -n +3 <file> | sort ...
(tail generará el contenido del archivo desde la tercera línea).
Si no te importa usar awk
, puedes aprovechar las habilidades de pipa incorporadas de awk
p.ej.
extract_data | awk ''NR<3{print $0;next}{print $0| "sort -r"}''
Esto imprime las dos primeras líneas al pie de la letra y canaliza el resto por sort
.
Tenga en cuenta que esto tiene la ventaja muy específica de poder seleccionar selectivamente partes de una entrada canalizada. todos los otros métodos sugeridos solo ordenarán los archivos simples que se pueden leer varias veces. Esto funciona en cualquier cosa.
Solo toma 2 líneas de código ...
head -1 test.txt > a.tmp;
tail -n+2 test.txt | sort -n >> a.tmp;
Para datos numéricos, se requiere -n. Para el orden alfa, el -n no es obligatorio.
Archivo de ejemplo:
$ cat test.txt
encabezamiento
8
5
100
1
-1
Resultado:
$ cat a.tmp
encabezamiento
-1
1
5
8
100
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile
Los paréntesis crean una subshell, terminando la stdout para que pueda canalizarla o redirigirla como si procediera de un solo comando.
cat file_name.txt | sed 1d | sort
Esto hará lo que quieras.
head -2 <your_file> && nawk ''NR>2'' <your_file> | sort
ejemplo:
> cat temp
10
8
1
2
3
4
5
> head -2 temp && nawk ''NR>2'' temp | sort -r
10
8
5
4
3
2
1