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 maneragtacpredeterminada).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 -ry tac.tacse 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 lasedsolución funciona para dichos archivos.al final de su comando ponga:
| tactac 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
taccomando, esto es útil para los nuevos usuarios que podrían terminar buscando el mismo tema.Si estás en
vimusofuente
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 -ren caso detacque no esté disponible.tacno es compatible con POSIX. Tampoco lo estail -r. Todavía no es infalible, pero esto mejora las probabilidades de que las cosas funcionen.tacestá disponible, pero se queda sin RAM e intercambia a la mitad del consumo de un flujo de entrada gigante. Falla, y luegotail -rlogra procesar el resto de la secuencia dando un resultado incorrecto.brew install coreutilsy el usogtacen lugar detacy si su complemento prefieren tac como un alias quegtacsi por ejemplo quieres un script de shell que lo utilizó multiplataforma (Linux, OSX)Pruebe el siguiente comando:
fuente
sed 's/^[0-9]*://g'nlpor defecto no podrá numerar líneas vacías. La-baopción está disponible en algunos sistemas, no es universal (HP / UX viene a mi mente, aunque desearía que no lo hiciera), mientrasgrep -nque 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
-neneneneneneney 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
taccomando.tacescatinverso. Ejemplo:fuente
Realmente me gusta la respuesta " tail -r ", pero mi respuesta favorita es ...
fuente
mawkUbuntu 14.04 LTS: funciona, por lo que no es específico de GNU awk. +1n++puede ser reemplazado conNREDITAR 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
tacdentro 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
nlí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 quetailtiene 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 nsi sutailno tiene la-ropció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\nlugar de20\n19...\2\n1\n.Puedes hacerlo con
vimstdinystdout. También puede usarexpara cumplir con POSIX .vimes solo el modo visual paraex. De hecho, puede usarexconvim -eovim -E(exmodo mejorado ).vimes útil porque, a diferencia de herramientas comosedesta, almacena el archivo para editarlo, mientras quesedse 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 llamadoveden 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
vedlugar: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 -rsolo funciona si la entrada ya está ordenada, que no es el caso aquí.revinvierte 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.