Tengo un archivo temp.txt, que quiero ordenar con el sortcomando en bash.
Quiero que los resultados ordenados reemplacen el archivo original.
Esto no funciona, por ejemplo (obtengo un archivo vacío):
sortx temp.txt > temp.txt
¿Se puede hacer esto en una línea sin recurrir a la copia en archivos temporales?
EDITAR: La -oopción es muy buena para sort. Usé sorten mi pregunta como ejemplo. Me encuentro con el mismo problema con otros comandos:
uniq temp.txt > temp.txt.
¿Existe una mejor solución general?

Respuestas:
fuente
sort --inplace *.txt? Eso sería increíblemente genialfind . -name \*.txt -exec sort {} -o {} \;A
sortnecesita ver todas las entradas antes de que pueda comenzar a generar. Por esta razón, elsortprograma puede ofrecer fácilmente una opción para modificar un archivo en el lugar:Específicamente, la documentación de GNU
sortdice:Mientras que la documentación de BSD
sortdice:Los comandos como
uniqpueden comenzar a escribir la salida antes de que terminen de leer la entrada. Por lo general, estos comandos no admiten la edición en el lugar (y sería más difícil para ellos admitir esta función).Por lo general, soluciona esto con un archivo temporal, o si absolutamente desea evitar tener un archivo intermedio, puede usar un búfer para almacenar el resultado completo antes de escribirlo. Por ejemplo, con
perl:Aquí, la parte de perl lee la salida completa de una
uniqvariable$_y luego sobrescribe el archivo original con estos datos. Puede hacer lo mismo en el lenguaje de secuencias de comandos que elija, tal vez incluso en Bash. Pero tenga en cuenta que necesitará suficiente memoria para almacenar el archivo completo, esto no es recomendable cuando se trabaja con archivos grandes.fuente
Aquí hay un enfoque más general, funciona con uniq, sort y otras cosas.
fuente
spongede los moreutils:cat file |frobnicate |sponge file.El comentario de Tobu sobre la esponja merece ser una respuesta por derecho propio.
Para citar de la página de inicio de moreutils :
Sin embargo,
spongesufre el mismo problema que comenta Steve Jessop aquí. Si alguno de los comandos de la canalización anteriorspongefalla, se sobrescribirá el archivo original.Uh-oh,
my-important-filese ha ido.fuente
set -o pipefailal comienzo de su secuencia de comandos, el error enmistyped_command my-important-fileharía que la secuencia de comandos salga inmediatamente, antes de ejecutarsesponge, preservando así el archivo importante.Aquí tienes, una línea:
Técnicamente, no se puede copiar a un archivo temporal y el comando 'mv' debería ser instantáneo.
fuente
Me gusta la
sort file -o filerespuesta, pero no quiero escribir el mismo nombre de archivo dos veces.Usando la expansión del historial de BASH :
agarra el primer argumento de la línea actual cuando presiona enter.
Una clasificación única en el lugar:
toma el último argumento de la línea actual.
fuente
Muchos han mencionado la opción -o . Aquí está la parte de la página de manual.
Desde la página del manual:
fuente
Esto tendría una gran limitación de memoria, pero podría usar awk para almacenar los datos intermedios en la memoria y luego volver a escribirlos.
fuente
>trunca el archivo antes de que el comando (uniqen este caso) lo lee.Una alternativa a
spongelas más comunessed:Funciona para cualquier comando (
sort,uniq,tac, ...) y los usos de la muy conocidased's-iopción (editar archivos en el lugar).Advertencia: intente
command fileprimero porque editar archivos en el lugar no es seguro por naturaleza.Explicación
En primer lugar, usted está diciendo
sedque no se imprima el (originales) líneas (-nopción ), y con la ayuda de lased'srcomando ybash' s Sustitución de proceso , el contenido generado por<(command file)será la salida guardada en su lugar .Haciendo las cosas aún más fáciles
Puede envolver esta solución en una función:
Ejemplo
fuente
Usa el argumento
--output=o-oProbé en FreeBSD:
fuente
Para agregar la
uniqcapacidad, ¿cuáles son las desventajas de:fuente
Lea sobre el editor no interactivo,
ex.fuente
Si insiste en usar el
sortprograma, debe usar un archivo intermedio; no creo quesorttenga una opción para ordenar en la memoria. Cualquier otro truco con stdin / stdout fallará a menos que pueda garantizar que el tamaño del búfer para stdin de sort es lo suficientemente grande para caber en todo el archivo.Editar: la culpa es mía.
sort temp.txt -o temp.txtfunciona excelente.fuente
Otra solución:
fuente
<>truco solo funciona en este caso porqueuniqes especial porque solo copia las líneas de entrada en las líneas de salida, dejando algunas en el camino. Sisedse usó otro comando (por ejemplo ) que cambiaría la entrada (por ejemplo, cambiaría cadaaenaa), entonces puede anularfilede formas que no tienen ningún sentido e incluso hacer un ciclo infinito, siempre que la entrada sea lo suficientemente grande (más de un búfer de lectura única).