Solución 1:
echo "$(uniq .bash_history)" > .bash_history
debe tener el resultado deseado. El subshell se ejecuta antes de .bash_history
se abre para escribir. Como se explica en la respuesta de Phil P, en el momento .bash_history
se lee en el comando original, ya ha sido truncado por el >
operador.
Solución 2:
Recomiendo usar sponge
de moreutils. Desde la página de manual:
DESCRIPTION
sponge reads standard input and writes it out to the specified file. Unlike
a shell redirect, sponge soaks up all its input before opening the output file.
This allows for constructing pipelines that read from and write to the same
file.
Para aplicar esto a su problema, intente:
uniq .bash_history | sponge .bash_history
Solución 3:
El problema es que su shell está configurando la canalización de comandos antes de ejecutar los comandos. No es una cuestión de "entrada y salida", es que el contenido del archivo ya se ha ido antes de que se ejecute uniq. Va algo como:
- El caparazón abre el
>
archivo de salida para escribir, truncándolo - El shell se configura para que se use el descriptor de archivo 1 (para stdout) para esa salida
- El shell ejecuta uniq, tal vez algo como execlp("uniq", "uniq", ".bash_history", NULL)
- uniq se ejecuta, abre .bash_history y no encuentra nada
Existen varias soluciones, incluida la edición en el lugar y el uso de archivos temporales que otros mencionan, pero la clave es comprender el problema, qué es lo que realmente está fallando y por qué.
Solución 4:
Otro truco para hacer esto, sin usar sponge
, es el siguiente comando:
{ rm .bash_history && uniq > .bash_history; } < .bash_history
Este es uno de los trucos descritos en el excelente artículo Edición de archivos "in situ" en backreference.org.
Básicamente, abre el archivo para leerlo y luego lo "elimina". Sin embargo, en realidad no se eliminó:hay un descriptor de archivo abierto que apunta a él, y mientras permanezca abierto, el archivo seguirá existiendo. Luego crea un nuevo archivo con el mismo nombre y escribe las líneas únicas en él.
Desventaja de esta solución:Si uniq
falla por alguna razón, su historial desaparecerá.
Solución 5:
usa esponja de moreutils
uniq .bash_history | sponge .bash_history