2011-08-12 11 views

Respuesta

4
#!/usr/bin/perl 

    use Tie::File; 
    for (@ARGV) { 
     tie my @array, 'Tie::File', $_ or die $!; 
     unshift @array, "A new line";   
    } 

para procesar todos los .py archivos en un directorio recursivamente ejecutar este comando en la shell:

find . -name '*.py' | xargs perl script.pl

+1

Prefiero 'perl -pi -e 'BEGIN {print" Una nueva línea "}' $ (buscar. -name '* .py')' :) – hobbs

+0

@hobbs: I Entérate de la idea, pero parece que no funciona para mí (en 5.10) –

5
for a in `find . -name '*.py'` ; do cp "$a" "$a.cp" ; echo "Added line" > "$a" ; cat "$a.cp" >> "$a" ; rm "$a.cp" ; done 
+3

Al final probablemente quería 'rm $ a.cp' – eumiro

+0

@eumiro: Gracias. Fijo. –

+1

@Didier: ¿quiso decir 'encontrar. -name * .py'? –

4
import os 
for root, dirs, files in os.walk(directory): 
    for file in files: 
     if file.endswith('.py') 
      file_ptr = open(file, 'r') 
      old_content = file_ptr.read() 
      file_ptr = open(file, 'w') 
      file_ptr.write(your_new_line) 
      file_ptr.write(old_content) 

Por lo que yo sé no se puede insertar en el comienzo o al final del archivo en pitón. Solo vuelva a escribir o anexar.

+0

+1 para hacerlo en python –

4

Esto

  1. caminar recursivamente todos los directorios a partir de la corriente de trabajo directorio
  2. modificar solo esos archivos s cuyo nombre termina con '.py'
  3. preservar los permisos de archivo (a diferencia de open(filename,'w').)

fileinput también le da la opción de realizar copias de seguridad de los archivos originales antes de modificarlos.


import fileinput 
import os 
import sys 

for root, dirs, files in os.walk('.'): 
    for line in fileinput.input(
      (os.path.join(root,name) for name in files if name.endswith('.py')), 
      inplace=True, 
      # backup='.bak' # uncomment this if you want backups 
      ): 
     if fileinput.isfirstline(): 
      sys.stdout.write('Add line\n{l}'.format(l=line)) 
     else: 
      sys.stdout.write(line) 
6
find . -name \*.py | xargs sed -i '1a Line of text here' 

Editar: desde el comentario de tchrist, manejar nombres de fichero con espacios.

Suponiendo que ha GNU encontrar y xargs (como se ha especificado la etiqueta de Linux en la pregunta)

find . -name \*.py -print0 | xargs -0 sed -i '1a Line of text here' 

Sin herramientas GNU, que haría algo como:

while IFS= read -r filename; do 
    { echo "new line"; cat "$filename"; } > tmpfile && mv tmpfile "$filename" 
done < <(find . -name \*.py -print) 
+1

Obtienes el premio por la forma más corta y más obvia de acercarte a esto. Usted tiene un error potencial con espacios en blanco en el directorio o nombres de archivos, pero eso es fácil de arreglar con '-print0' a la izquierda y' -0' a la derecha. – tchrist

+0

@tchrist: ¿No se limitará a imprimir la respuesta a STDOUT en lugar de agregar la línea al principio de cada archivo? –

+0

@David, no, la opción '-i' para sed significa actualizar el archivo en el lugar. No verá nada en stdout. –

1

Lo que es ¿La forma más fácil de hacerlo utilizando Perl, Python o script de shell?

Usaría Perl, pero eso es porque conozco a Perl mucho mejor de lo que conozco a Python. Diablos, tal vez haría esto en Python solo para aprenderlo un poco mejor.

La forma más fácil manera es utilizar el lenguaje que usted está familiarizado con y puede trabajar con ellos. Y, probablemente también sea la mejor manera.

Si se trata de todos los scripts de Python, supongo que conoces Python o tienes acceso a un grupo de personas que conocen Python. Entonces, probablemente estés mejor haciendo el proyecto en Python.

Sin embargo, es posible con scripts de shell también, y si conoce el shell lo mejor, sea mi invitado.Aquí hay un poco, shell script, no está comprobado derecha de la parte superior de mi cabeza:

find . -type f -name "*.py" | while read file 
do 
    sed 'i\ 
I want to insert this line 
' $file > $file.temp 
    mv $file.temp $file 
done 
+0

+1 para usar la herramienta correcta, 'sed', pero tienes un error: deberías decir' -print0' para 'encontrar' y conectar a 'mientras IFS = read -d' \ 0 '-r file', para evitar problemas con nombres de archivos problemáticos. – Sorpigal

+0

En realidad, los espacios o las pestañas en los nombres no son un gran problema aquí (aunque LF en el medio de los nombres de los archivos). Revisando mi programa, el gran problema es que no cité la variable '$ file'. Si hubiera un espacio en el nombre del archivo, mi programa no funcionaría. –

Cuestiones relacionadas