2010-04-11 9 views
22

no puede conseguir la edición en Perl de una sola línea que se ejecutan bajo ActivePerl para trabajar a menos que los precisen con una extensión de copia de seguridad:¿Por qué tengo que especificar el modificador -i con una extensión de copia de seguridad cuando uso ActivePerl?

C:\> perl -i -ape "splice (@F, 2, 0, q(inserted text)); $_ = qq(@F\n);" file1.txt 
Can't do inplace edit without backup. 

El mismo comando con -i.bak o -i.orig funciona un lujo, pero crea un archivo de copia de seguridad no deseados en el proceso.

¿Hay alguna forma de evitar esto?

Respuesta

29

Esto es una limitación de Windows/MS-DOS. De acuerdo con perldiag:

Estás en un sistema como el MS-DOS que se confunde si se intenta leer de un archivo borrado (pero todavía abierto). Tienes que decir -i.bak, o algo así.

-i aplicación de Perl hace que se elimine file1.txt mientras se mantiene un identificador abierto a ella, a continuación, volver a crear el archivo con el mismo nombre. Esto le permite 'leer' archivo1.txt aunque se haya eliminado y se vuelva a crear. Desafortunadamente, Windows/MS-DOS no le permite eliminar un archivo que tiene un controlador abierto asociado, por lo que este mecanismo no funciona.

Su mejor opción es utilizar -i.bak y luego eliminar el archivo de copia de seguridad. Esto al menos le brinda cierta protección, por ejemplo, puede optar por no eliminar la copia de seguridad si perl sale con un código de salida distinto de cero. Algo como:

perl -i.bak -ape "splice...." file1.txt && del file1.bak 
+0

Por lo tanto, es una limitación de Windows. Esperaba que no tuviera que 'desvincular' la copia de seguridad con un comando separado ... parece que tendré que hacerlo. Gracias por la ayuda. – Zaid

+0

No del todo relacionado, pero la edición in situ en sed en Windows parece funcionar para mí. Veo que su ejemplo no funcionaría en sed, pero podría ser útil saberlo. – Mike

+0

@Mike: en mi extremo, la edición 'sed' in situ deja archivos temporales como, por ejemplo, 'sedGihEwg' en el sistema de archivos: ¿el tuyo no? ¿Qué versión tienes? Estoy usando 'GNU sed versión 4.2.1'. – zb226

0

Ejemplo con recursivo modificar y eliminar ambos hechos por find. Funciona en, por ejemplo, mingw git bash en windows.

$ find . -name "*.xml" -print0 | xargs -0 perl -p -i.bak -e 's#\s*<property name="blah" value="false" />\s*##g' 
$ find . -name "*.bak" -print0 | xargs -0 rm 

Valores binarios terminados entre find/xargs para manejar espacios. S/prefijo inusual para evitar manipular xml en el término de búsqueda. Esto supone que no tenía ningún archivo .bak dando vueltas para comenzar.

Cuestiones relacionadas