Tengo un archivo temp.txt, que quiero ordenar con el sort
comando 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 -o
opción es muy buena para sort
. Usé sort
en 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
sort
necesita ver todas las entradas antes de que pueda comenzar a generar. Por esta razón, elsort
programa puede ofrecer fácilmente una opción para modificar un archivo en el lugar:Específicamente, la documentación de GNU
sort
dice:Mientras que la documentación de BSD
sort
dice:Los comandos como
uniq
pueden 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
uniq
variable$_
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
sponge
de 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,
sponge
sufre el mismo problema que comenta Steve Jessop aquí. Si alguno de los comandos de la canalización anteriorsponge
falla, se sobrescribirá el archivo original.Uh-oh,
my-important-file
se ha ido.fuente
set -o pipefail
al comienzo de su secuencia de comandos, el error enmistyped_command my-important-file
harí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 file
respuesta, 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 (uniq
en este caso) lo lee.Una alternativa a
sponge
las más comunessed
:Funciona para cualquier comando (
sort
,uniq
,tac
, ...) y los usos de la muy conocidased
's-i
opción (editar archivos en el lugar).Advertencia: intente
command file
primero porque editar archivos en el lugar no es seguro por naturaleza.Explicación
En primer lugar, usted está diciendo
sed
que no se imprima el (originales) líneas (-n
opción ), y con la ayuda de lased
'sr
comando 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-o
Probé en FreeBSD:
fuente
Para agregar la
uniq
capacidad, ¿cuáles son las desventajas de:fuente
Lea sobre el editor no interactivo,
ex
.fuente
Si insiste en usar el
sort
programa, debe usar un archivo intermedio; no creo quesort
tenga 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.txt
funciona excelente.fuente
Otra solución:
fuente
<>
truco solo funciona en este caso porqueuniq
es especial porque solo copia las líneas de entrada en las líneas de salida, dejando algunas en el camino. Sised
se usó otro comando (por ejemplo ) que cambiaría la entrada (por ejemplo, cambiaría cadaa
enaa
), entonces puede anularfile
de 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).