Un amigo mío señala que si haces:
perl -pi.bak -e 's/foo/bar/' somefile
cuando "somefile" es en realidad un enlace simbólico, perl hace exactamente lo que dicen los documentos:
Para ello, renombra el archivo de entrada, abre el archivo de salida con el nombre original y selecciona ese archivo de salida como predeterminado para las declaraciones print (). La extensión, si se proporciona, se utiliza para modificar el nombre del archivo antiguo para hacer una copia de seguridad [...]
Lo que da como resultado un nuevo enlace simbólico "somefile.bak" que apunta al archivo real sin cambios, y un nuevo archivo regular "somefile" con los cambios.
En muchos casos, seguir el enlace simbólico sería el comportamiento deseado (incluso si deja ambigua la ubicación correcta del archivo .bak). ¿Hay una manera simple de hacer esto que no sea probar los enlaces simbólicos en un contenedor y manejar el caso adecuadamente?
( sedhace lo mismo, por lo que vale).

-p -ien tu guión.Respuestas:
Me pregunto si la pequeña
spongeutilidad de propósito general ("absorber la entrada estándar y escribir en un archivo") de moreutils será útil en este caso y si seguirá el enlace simbólico.El autor describe
spongeasí:fuente
spongepara tal uso en la práctica? En cuanto a mí: todavía no. ¿Podría por favor dejar un comentario que indique si se comportó en una prueba como se quería aquí? Oh, veo el comentario. ¡Gracias por la confirmación!fileen su ejemplo anterior hay un enlace simbólico, el enlace se deja solo y el archivo real cambia.Si sabe a
somefileciencia cierta que es un enlace simbólico, puede proporcionar explícitamente la ruta completa al archivo con lo siguiente:perl -pi.bak -e 's/foo/bar/' $(readlink somefile)De esa manera, el enlace simbólico original permanece intacto ya que el reemplazo ahora se realiza directamente con el archivo original.
fuente
readlinktodavía puede ser otro enlace simbólico. Lo mejor sería usar-fo-ecuando esté disponible ozsh's$file:Po(:P)calificador global como se muestra en @ikegami para obtener una ruta sin enlace simbólico.Si se trata de un solo archivo que, el comando se vería de la siguiente manera:
La solución entonces es la siguiente:
Esto maneja enlaces simbólicos y no simbólicos.
Si se trata de una cantidad arbitrariamente grande de archivos, el comando se vería de la siguiente manera:
La solución entonces es la siguiente:
Esto maneja enlaces simbólicos y no simbólicos.
La advertencia
readlinkno es un comando estándar, por lo que su presencia, sus argumentos y su funcionalidad varían según el sistema, así que asegúrese de verificar su documentación. Por ejemplo, algunas implementaciones tienen-f(que también podría usar aquí), pero no-e, algunas tampoco.busyboxSereadlink -fcomporta como GNUreadlink -e. Y algunos sistemas tienen unrealpathcomando en lugar dereadlinkque generalmente se comporta como GNUreadlink -f.Tenga en cuenta que con GNU
readlink -e, los enlaces simbólicos que no se pueden resolver a un archivo existente se eliminan silenciosamente.fuente
$var:Pno funciona para mí. (X='tmp' zsh -c 'perl -E"say for @ARGV" $X:P'salidastmp:P)$var:P. Con versiones anteriores, siempre puede usar$var:Aen su lugar. Consulte el manual para conocer las diferencias y zsh.org/mla/users/2016/msg00593.html para conocer los motivos de la introducción:P(larealpath()interfaz real ).:Ase agregó en 4.3.10 (2009), GNUreadlink -zen 2012, no conozco ninguna otrareadlinkimplementación que admita-z). Tenga en cuenta que con GNUxargs, generalmente desea la-ropción a menos que pueda garantizar que la entrada no estará vacía. Aquí, no es gran cosa (a menos que elperlcódigo contenga una declaraciónBEGIN/END), solo recibiría una-i used with no filenames on the command line, reading from STDIN.advertencia si eso sucede.-rla documentación. Pensé que hice lo contrario de lo que hace. Readded