Respuestas:
Usando sedpara emular tac:
sed '1!G;h;$!d' ${inputfile}
sedone-liner. Consulte "36. Orden inverso de líneas (emular" tac "comando Unix)". en el famoso Sed One-Liners explicado para una explicación completa de cómo funciona.
sort, existe la posibilidad de que use un archivo temporal).
Con ed:
ed -s infile <<IN
g/^/m0
,p
q
IN
Si está en BSD/ OSX(y con suerte pronto en GNU/ linuxtambién, ya que será POSIX ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
a través de awk one liners
awk 'a=$0RS a{}END{printf a}'
but your first perl reverse <> `es la respuesta mejor / más rápida en la página (para mí), 10 veces más rápido que esta awkrespuesta (todos los awk anseres son casi iguales, en cuanto al tiempo)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Como pediste hacerlo en bash, aquí hay una solución que no utiliza awk, sed o perl, solo una función bash:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
La salida de
echo 'a
b
c
d
' | reverse
es
d
c
b
a
Como se esperaba.
Pero tenga en cuenta que las líneas se almacenan en la memoria, una línea en cada instancia recursivamente llamada instancia de la función. Tan cuidadoso con los archivos grandes.
Puedes canalizarlo a través de:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Los awkprefijos de cada línea con el número de línea seguido de un espacio. El sortinvierte el orden de las líneas de clasificación en el primer campo (número de línea) en orden inverso, estilo numérico. Y las sedtiras de los números de línea.
El siguiente ejemplo muestra esto en acción:
pax$ echo 'a
b
c
d
e
f
g
h
i
j
k
l' | awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Produce:
l
k
j
i
h
g
f
e
d
c
b
a
cat -nactúa comoawk '{print NR" "$0}'
En perl:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{')
reverse<)es rápido: ¡bien! pero el "realmente feo" es extremadamente lento a medida que aumenta el número de líneas. !! ....
-nfue superfluo allí, gracias.
sort).
Solución solo BASH
lea el archivo en la matriz bash (una línea = un elemento de la matriz) e imprima la matriz en orden inverso:
i=0
while read line[$i] ; do
i=$(($i+1))
done < FILE
for (( i=${#line[@]}-1 ; i>=0 ; i-- )) ; do
echo ${line[$i]}
done
while..read.
IFS=''y read -rpara evitar que todo tipo de fugas y la eliminación de IFS final lo arruinen. Sin mapfile ARRAY_NAMEembargo, creo que bash builtin es una mejor solución para leer en matrices.
Bash, con los mapfilecomentarios mencionados en Fiximan, y en realidad una versión posiblemente mejor:
# last [LINES=50]
_last_flush(){ BUF=("${BUF[@]:$(($1-LINES)):$1}"); } # flush the lines, can be slow.
last(){
local LINES="${1:-10}" BUF
((LINES)) || return 2
mapfile -C _last_flush -c $(( (LINES<5000) ? 5000 : LINES+5 )) BUF
BUF=("${BUF[@]}") # Make sure the array subscripts make sence, can be slow.
((LINES="${#BUF[@]}" > LINES ? LINES : "${#BUF[@]}"))
for ((i="${#BUF[@]}"; i>"${#BUF[@]}"-LINES; i--)); do echo -n "${BUF[i]}"; done
}
Su rendimiento es básicamente comparable a la sedsolución, y se acelera a medida que disminuye el número de líneas solicitadas.
Simple do this with your file to sort the data in reverse order, and it should be unique.
sed -n '1h; 1d; G; h; $ p'
como se muestra aquí:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Resultado:
c a f e
awk '{print NR" "$0}' | sort -nr