Me gustaría invertir el orden de las líneas en un archivo de texto (o stdin), preservando el contenido de cada línea.
Entonces, es decir, comenzando con:
foo
bar
baz
Me gustaría terminar con
baz
bar
foo
¿Existe una utilidad de línea de comandos UNIX estándar para esto?
shell
unix
command-line
Scotty Allen
fuente
fuente
perl -e 'print reverse <>'
pero probablemente también se aplica a otros métodos).Respuestas:
Cola BSD:
Referencia: páginas de manual de FreeBSD , NetBSD , OpenBSD y OS X.
fuente
También vale la pena mencionar:
tac
(el, ejem, reverso decat
). Parte de coreutils .Voltear un archivo a otro
fuente
brew install coreutils
(se instala de maneragtac
predeterminada).echo -n "abc\ndee" > test; tac test
.Existen los conocidos trucos sed :
(Explicación: anteponer una línea no inicial para retener el búfer, intercambiar la línea y retener el búfer, imprimir la línea al final)
Alternativamente (con una ejecución más rápida) de los awk one-liners :
Si no puedes recordar eso,
En un sistema con utilidades GNU, las otras respuestas son más simples, pero no todo el mundo es GNU / Linux ...
fuente
tail -r
y tac.tac
se espera que maneje archivos grandes arbitrarios que no caben en la memoria (aunque la longitud de la línea aún es limitada). No está claro si lased
solución funciona para dichos archivos.al final de su comando ponga:
| tac
tac hace exactamente lo que está pidiendo: "Escribir cada ARCHIVO en la salida estándar, la última línea primero".
tac es lo opuesto a cat :-).
fuente
tac
comando, esto es útil para los nuevos usuarios que podrían terminar buscando el mismo tema.Si estás en
vim
usofuente
ejemplo:
fuente
Pruebe
tac
, que funciona en Linux, y si eso no funcionatail -r
, use , que funciona en BSD y OSX.fuente
tac myfile.txt
? ¿Qué me estoy perdiendo?tail -r
en caso detac
que no esté disponible.tac
no es compatible con POSIX. Tampoco lo estail -r
. Todavía no es infalible, pero esto mejora las probabilidades de que las cosas funcionen.tac
está disponible, pero se queda sin RAM e intercambia a la mitad del consumo de un flujo de entrada gigante. Falla, y luegotail -r
logra procesar el resto de la secuencia dando un resultado incorrecto.brew install coreutils
y el usogtac
en lugar detac
y si su complemento prefieren tac como un alias quegtac
si por ejemplo quieres un script de shell que lo utilizó multiplataforma (Linux, OSX)Pruebe el siguiente comando:
fuente
sed 's/^[0-9]*://g'
nl
por defecto no podrá numerar líneas vacías. La-ba
opción está disponible en algunos sistemas, no es universal (HP / UX viene a mi mente, aunque desearía que no lo hiciera), mientrasgrep -n
que siempre numerará cada línea que coincida con la expresión regular (en este caso vacía).cut -d: -f2-
Solo Bash :) (4.0+)
fuente
-nenenenenenene
y sea testigo de la razón por la cual la gente recomienda usar siempre enprintf '%s\n'
lugar deecho
.El método más simple es usar el
tac
comando.tac
escat
inverso. Ejemplo:fuente
Realmente me gusta la respuesta " tail -r ", pero mi respuesta favorita es ...
fuente
mawk
Ubuntu 14.04 LTS: funciona, por lo que no es específico de GNU awk. +1n++
puede ser reemplazado conNR
EDITAR lo siguiente genera una lista ordenada aleatoriamente de números del 1 al 10:
donde los puntos se reemplazan con un comando real que invierte la lista
tac
python: usando [:: - 1] en sys.stdin
fuente
Para la solución de sistema operativo cruzado (es decir, OSX, Linux) que puede usar
tac
dentro de un script de shell, use homebrew como otros han mencionado anteriormente, luego solo alias tac de esta manera:Instalar lib
Para MacOS
Para linux debian
Luego agrega alias
fuente
Esto funcionará tanto en BSD como en GNU.
fuente
Si desea modificar el archivo en su lugar, puede ejecutar
Esto elimina la necesidad de crear un archivo temporal y luego eliminar o cambiar el nombre del original y tiene el mismo resultado. Por ejemplo:
Basado en la respuesta por ephemient , que hizo casi, pero no del todo, lo que quería.
fuente
Me sucede que quiero obtener las últimas
n
líneas de un archivo de texto muy grande de manera eficiente .Lo primero que probé es
tail -n 10000000 file.txt > ans.txt
, pero lo encontré muy lento, ya quetail
tiene que buscar la ubicación y luego retroceder para imprimir los resultados.Cuando me di cuenta, me cambio a otra solución:
tac file.txt | head -n 10000000 > ans.txt
. ¡Esta vez, la posición de búsqueda solo necesita moverse desde el final hasta la ubicación deseada y ahorra un 50% de tiempo !Llevar el mensaje a casa:
Úselo
tac file.txt | head -n n
si sutail
no tiene la-r
opción.fuente
Mejor solución:
fuente
Para usuarios de Emacs:
C-x h
(seleccione el archivo completo) y luegoM-x reverse-region
. También funciona solo para seleccionar partes o líneas y revertirlas.fuente
Veo muchas ideas interesantes. Pero prueba mi idea. Canaliza tu texto en esto:
que supone que el carácter '~' no está en el archivo. Esto debería funcionar en cada shell de UNIX desde 1961. O algo así.
fuente
Tenía la misma pregunta, pero también quería que la primera línea (encabezado) permaneciera en la parte superior. Entonces necesitaba usar el poder de awk
PS también funciona en cygwin o gitbash
fuente
1\n20\n19...2\n
lugar de20\n19...\2\n1\n
.Puedes hacerlo con
vim
stdin
ystdout
. También puede usarex
para cumplir con POSIX .vim
es solo el modo visual paraex
. De hecho, puede usarex
convim -e
ovim -E
(ex
modo mejorado ).vim
es útil porque, a diferencia de herramientas comosed
esta, almacena el archivo para editarlo, mientras quesed
se usa para transmisiones. Es posible que pueda usarawk
, pero tendría que almacenar manualmente todo en una variable.La idea es hacer lo siguiente:
g/^/m0
. Esto significa globalmente, para cada líneag
; coincide con el inicio de la línea, que coincide con cualquier cosa^
; muévalo después de la dirección 0, que es la línea 1m0
.%p
. Esto significa para el rango de todas las líneas%
; imprime la líneap
.q!
. Esto significa dejar de fumarq
; enérgicamente!
.Cómo hacer que esto sea reutilizable
Uso un script que llamo
ved
(editor de vimsed
) para usar vim para editarstdin
. Agregue esto a un archivo llamadoved
en su ruta:Estoy usando un
+
comando en lugar de+'%p' +'q!'
, porque vim te limita a 10 comandos. Por lo tanto, fusionarlos le permite"$@"
tener 9+
comandos en lugar de 8.Entonces puedes hacer:
Si no tienes vim 8, pon esto en su
ved
lugar:fuente
o
o
fuente
tail -r funciona en la mayoría de los sistemas Linux y MacOS
seq 1 20 | cola -r
fuente
o
fuente
sort -r
solo funciona si la entrada ya está ordenada, que no es el caso aquí.rev
invierte los caracteres por línea pero mantiene intacto el orden de las líneas, que tampoco es lo que Scotty solicitó. Entonces, esta respuesta es en realidad ninguna respuesta.