¿Cómo implementar modismos bash comunes en Python? [cerrado]
Actualmente hago mi manipulación de archivos de texto a través de un montón de AWK, sed, Bash y un poquito de Perl que no recuerdo bien.
He mencionado algunos lugares en los que Python es bueno para este tipo de cosas. ¿Cómo puedo usar Python para reemplazar los scripts de Shell, AWK, sed y amigos?
Cualquier caparazón tiene varios conjuntos de características.
Los comandos esenciales de Linux/Unix. Todos estos están disponibles a través de la biblioteca de subprocesos . Esta no siempre es la mejor primera opción para ejecutar todos los comandos externos. Mire también ashutil para ver algunos comandos que son comandos separados de Linux, pero que probablemente podría implementar directamente en sus scripts de Python. Otro gran lote de comandos de Linux se encuentra en la biblioteca del sistema operativo ; Puedes hacerlo de forma más sencilla en Python.
Y... ¡bonificación! -- mas rapido. Cada comando separado de Linux en el shell (con algunas excepciones) bifurca un subproceso. Al usar Python
shutil
yos
módulos, no bifurcas un subproceso.Las características del entorno shell. Esto incluye cosas que configuran el entorno de un comando (directorio actual y variables de entorno y demás). Puede administrar esto fácilmente desde Python directamente.
Las funciones de programación del shell. Esta es toda la verificación del código de estado del proceso, los diversos comandos lógicos (if, while, for, etc.), el comando de prueba y todos sus parientes. Lo de la definición de funciones. Todo esto es mucho, mucho más fácil en Python. Esta es una de las grandes victorias al deshacerse de bash y hacerlo en Python.
Características de interacción. Esto incluye el historial de comandos y demás. No necesitas esto para escribir scripts de shell. Esto es sólo para la interacción humana y no para escribir guiones.
Las funciones de administración de archivos de shell. Esto incluye redirección y canalizaciones. Esto es más complicado. Gran parte de esto se puede hacer con subprocesos. Pero algunas cosas que son fáciles en el shell no son agradables en Python. Específicamente cosas como
(a | b; c ) | something >result
. Esto ejecuta dos procesos en paralelo (con la salida dea
como entrada ab
), seguidos de un tercer proceso. El resultado de esa secuencia se ejecuta en paralelosomething
y el resultado se recopila en un archivo denominadoresult
. Eso es simplemente complejo de expresar en cualquier otro idioma.
Los programas específicos (awk, sed, grep, etc.) a menudo se pueden reescribir como módulos de Python. No te excedas. Reemplace lo que necesita y evolucione su módulo "grep". No empieces a escribir un módulo de Python que reemplace a "grep".
Lo mejor es que puedes hacerlo en pasos.
- Reemplace AWK y PERL con Python. Deja todo lo demás en paz.
- Considere reemplazar GREP con Python. Esto puede ser un poco más complejo, pero su versión de GREP puede adaptarse a sus necesidades de procesamiento.
- Considere reemplazar FIND con bucles de Python que usen
os.walk
. Esta es una gran victoria porque no generas tantos procesos. - Considere reemplazar la lógica de shell común (bucles, decisiones, etc.) con scripts de Python.
Sí, claro :)
Eche un vistazo a estas bibliotecas que le ayudarán a no volver a escribir scripts de shell (lema de Plumbum).
- Plomo
- Sargento
- sh
Además, si desea reemplazar awk, sed y grep con algo basado en Python, le recomiendo pyp -
"The Pyed Piper", o pyp, es una herramienta de manipulación de texto de línea de comandos de Linux similar a awk o sed, pero que utiliza métodos estándar de cadenas y listas de Python, así como funciones personalizadas desarrolladas para generar resultados rápidos en un entorno de producción intenso.
Acabo de descubrir cómo combinar las mejores partes de bash e ipython. Hasta ahora esto me parece más cómodo que usar subprocesos y demás. Puede copiar fácilmente grandes partes de scripts bash existentes y, por ejemplo, agregar manejo de errores en Python :) Y aquí está mi resultado:
#!/usr/bin/env ipython3
# *** How to have the most comfort scripting experience of your life ***
# ######################################################################
#
# … by using ipython for scripting combined with subcommands from bash!
#
# 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy # creates new ipy-file
#
# 2. chmod +x scriptname.ipy # make in executable
#
# 3. starting with line 2, write normal python or do some of
# the ! magic of ipython, so that you can use unix commands
# within python and even assign their output to a variable via
# var = !cmd1 | cmd2 | cmd3 # enjoy ;)
#
# 4. run via ./scriptname.ipy - if it fails with recognizing % and !
# but parses raw python fine, please check again for the .ipy suffix
# ugly example, please go and find more in the wild
files = !ls *.* | grep "y"
for file in files:
!echo $file | grep "p"
# sorry for this nonsense example ;)
Consulte los documentos de IPython sobre los comandos del shell del sistema y su uso como shell del sistema .
A partir de 2015 y el lanzamiento de Python 3.4, ahora hay un shell interactivo para el usuario razonablemente completo disponible en: http://xon.sh/ o https://github.com/scopatz/xonsh
El vídeo de demostración no muestra el uso de tuberías, pero SON compatibles cuando están en el modo Shell predeterminado.
Xonsh ('concha') se esfuerza mucho en emular bash, por lo que cosas para las que ya has ganado memoria muscular, como
env | uniq | sort -r | grep PATH
o
my-web-server 2>&1 | my-log-sorter
seguirá funcionando bien.
El tutorial es bastante extenso y parece cubrir una cantidad significativa de la funcionalidad que alguien generalmente esperaría en un indicador ash o bash:
- ¡Compila, evalúa y ejecuta!
- Historial de comandos y finalización de pestañas
- Ayuda y Superayuda con
?
y??
- Alias y mensajes personalizados
- Ejecuta comandos y/o
*.xsh
scripts que también se pueden importar - Variables de entorno, incluida la búsqueda con
${}
- Redirección y combinación de entrada/salida
- Trabajos en segundo plano y control de trabajos
- Anidamiento de subprocesos, tuberías y coprocesos
- Modo subproceso cuando existe un comando, modo Python en caso contrario
- Subproceso capturado con
$()
, Subproceso no capturado con$[]
, Evaluación de Python con@()
- Nombre de archivo global con
*
o expresión regular Nombre de archivo global con comillas invertidas