scripting - udemy - regex automate the boring stuff
Nano hacks: programas pequeños más útiles que has codificado o encuentras (15)
Es la primera gran virtud de los programadores. Todos nosotros, en un momento u otro, automatizamos una tarea con un poco de código descartable. A veces lleva un par de segundos tapping en un trazador de líneas, a veces pasamos una cantidad de tiempo exorbitante al automatizar una tarea de dos segundos y luego nunca volver a usarla.
¿Qué truco tan pequeño has encontrado lo suficientemente útil como para reutilizarlo ? ¿Hasta llegar a hacer un alias?
Nota: antes de responder, compruebe para asegurarse de que todavía no esté en los trucos favoritos de la línea de comandos usando BASH o las preguntas de una sola línea de perl / ruby.
Aquí hay un filtro que pone las comas en el medio de cualquier número grande en la entrada estándar.
$ cat ~/bin/comma
#!/usr/bin/perl -p
s/(/d{4,})/commify($1)/ge;
sub commify {
local $_ = shift;
1 while s/^([ -+]?/d+)(/d{3})/$1,$2/;
return $_;
}
Normalmente termino utilizándolo para largas listas de salida de grandes números, y me canso de contar los lugares decimales. Ahora en lugar de ver
-rw-r--r-- 1 alester alester 2244487404 Oct 6 15:38 listdetail.sql
Puedo ejecutar eso como ls -l | comma
ls -l | comma
y ver
-rw-r--r-- 1 alester alester 2,244,487,404 Oct 6 15:38 listdetail.sql
Cada vez que escribo una lista inteligente de comprensión o uso de map / reduce en python. Había uno como este:
if reduce(lambda x, c: locks[x] and c, locknames, True):
print "Sub-threads terminated!"
La razón por la que recuerdo eso es que lo inventé yo mismo, y luego vi exactamente el mismo código en el sitio web de otra persona. Hoy en día, probablemente sea como:
if all(map(lambda z: locks[z], locknames)):
print "ya trik"
Codifiqué una secuencia de comandos de Perl para mapear dependencias, sin entrar en un bucle infinito, para un programa heredado de C que heredé .... que también tenía un problema de dependencia de diamantes.
Escribí un pequeño programa que me enviaba un correo electrónico cuando recibía correos electrónicos de amigos en una cuenta de correo electrónico que rara vez se usaba.
Escribí otro pequeño programa que me envió mensajes de texto si cambia la dirección IP de mi casa.
Para nombrar unos pocos.
Esto se remonta a mis días de COBOL, pero tenía dos programas COBOL genéricos, uno por lotes y otro en línea (la gente del mainframe sabrá cuáles son). Eran conchas de un programa que podía tomar cualquier conjunto de parámetros y / o archivos y ejecutarse, por lotes o ejecutarse en una región de prueba IMS. Los tuve configurados para que, dependiendo de los parámetros, pudiera acceder a archivos, bases de datos (DB2 o IMS DB) o simplemente manipular el almacenamiento en funcionamiento o lo que sea.
Fue genial porque pude probar esa función de fecha sin adivinar o probar por qué hubo truncamiento o por qué había una base de datos ABEND. Los programas crecieron en tamaño a medida que pasó el tiempo para incluir todo tipo de pruebas y convertirse en un elemento básico del grupo de desarrollo. Todos sabían dónde residía el código y los incluyeron en sus pruebas unitarias también. Esos programas llegaron a ser tan grandes (la mayoría de los exámenes del código fueron comentados) y todo fue contribuido por personas a través de los años. ¡Ahorraron tanto tiempo y resolvieron tantos desacuerdos!
Hace años, construí un conjunto de aplicaciones en una plataforma de aplicaciones web personalizada en PERL. Una característica interesante fue convertir cadenas de consulta SQL en oraciones legibles para humanos que describieron cuáles fueron los resultados.
El código fue relativamente corto, pero el efecto final fue bueno.
Lo siento, no tengo el código exacto a mano, pero codifiqué una expresión regular para buscar código fuente en VS.Net que me permitió buscar cualquier cosa que no estuviera en los comentarios. Me resultó muy útil en un proyecto en particular en el que estaba trabajando, donde las personas insistían en que el código de comentarios era una buena práctica, en caso de que quisieras volver atrás y ver qué hacía el código.
Tengo 20 o 30 de estas cosas por ahí porque una vez que codifiqué el marco para mi aplicación de consola estándar en Windows, prácticamente puedo incluir cualquier lógica que quiera, así que obtuve muchas de estas pequeñas cosas que resuelven problemas específicos. .
Supongo que los que estoy usando mucho en este momento es una aplicación de consola que toma stdin y colorea la salida en función de los perfiles xml que combinan las expresiones regulares con los colores. Lo uso para ver mis archivos de registro de compilaciones. El otro es un iniciador de línea de comando, así que no contaminé mi env PATH var y de todos modos superaría el límite en algunos sistemas, es decir, win2k.
Tengo dos scripts ruby que modifico regularmente para descargar todos los webcomics. Extremadamente práctico! Nota: Requieren wget, entonces probablemente Linux. Nota 2: léelos antes de probarlos, necesitan un poco de modificación para cada sitio.
Descargador basado en fecha:
#!/usr/bin/ruby -w
Day = 60 * 60 * 24
Fromat = "hjlsdahjsd/comics/st%Y%m%d.gif"
t = Time.local(2005, 2, 5)
MWF = [1,3,5]
until t == Time.local(2007, 7, 9)
if MWF.include? t.wday
`wget #{t.strftime(Fromat)}`
sleep 3
end
t += Day
end
O puede usar el número basado en uno:
#!/usr/bin/ruby -w
Fromat = "http://fdsafdsa/comics/%08d.gif"
1.upto(986) do |i|
`wget #{sprintf(Fromat, i)}`
sleep 1
end
Tengo una pequeña aplicación que ejecutar y arroja un GUID en el portapapeles. Puedes ejecutarlo / noui o no. Con UI, es un botón único que arroja un nuevo GUID cada vez que hace clic en él. Sin él, cae uno nuevo y luego sale.
La uso principalmente desde dentro de VS. Lo tengo como una aplicación externa y asignado a un acceso directo. Estoy escribiendo una aplicación que depende mucho de xaml y guids, así que siempre encuentro que necesito pegar un nuevo guid en xaml ...
Uso esta secuencia de comandos en Linux variados para comprobar si una copia de directorio entre máquinas (o para CD / DVD) funcionó o si la copia (por ej. Nombres de archivo ext3 utf8 -> fusebl k) ha mutilado caracteres especiales en los nombres de archivo.
#!/bin/bash
## dsum Do checksums recursively over a directory.
## Typical usage: dsum <directory> > outfile
export LC_ALL=C # Optional - use sort order across different locales
if [ $# != 1 ]; then echo "Usage: ${0/*///} <directory>" 1>&2; exit; fi
cd $1 1>&2 || exit
#findargs=-follow # Uncomment to follow symbolic links
find . $findargs -type f | sort | xargs -d''/n'' cksum
encontré esto en dotfiles.org solo hoy. es muy simple, pero inteligente. Me sentí estúpido por no haberlo pensado yo mismo.
###
### Handy Extract Program
###
extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xvjf $1 ;;
*.tar.gz) tar xvzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 ;;
*.tbz2) tar xvjf $1 ;;
*.tgz) tar xvzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "''$1'' cannot be extracted via >extract<" ;;
esac
else
echo "''$1'' is not a valid file"
fi
}
En lugar de tener que abrir archivos repetidamente en el Analizador de consultas SQL y ejecutarlos, encontré la sintaxis necesaria para hacer un archivo por lotes, y luego pude ejecutar 100 a la vez. ¡Oh dulce y dulce alegría! Lo he usado desde entonces.
isqlw -S servername -d dbname -E -i F:/blah/whatever.sql -o F:/results.txt
Me conecto constantemente a varios servidores Linux desde mi escritorio a lo largo de mi jornada laboral, así que creé algunos alias que lanzarán un xterm
en esas máquinas y establecerán el título, el color de fondo y otros ajustes:
alias x="xterm" # local
alias xd="ssh -Xf me@development_host xterm -bg aliceblue -ls -sb -bc -geometry 100x30 -title Development"
alias xp="ssh -Xf me@production_host xterm -bg thistle1 ..."
También tengo un montón de servidores con los que me conecto frecuentemente, pero todos están en mi red local. Este script de Ruby imprime el comando para crear alias para cualquier máquina con ssh abierto:
#!/usr/bin/env ruby
require ''rubygems''
require ''dnssd''
handle = DNSSD.browse(''_ssh._tcp'') do |reply|
print "alias #{reply.name}=''ssh #{reply.name}.#{reply.domain}'';"
end
sleep 1
handle.stop
Úselo así en su .bash_profile
:
eval `ruby ~/.alias_shares`
Este guion salvó mi carrera!
Hace unos años, estaba trabajando de forma remota en una base de datos de clientes. Actualicé un envío para cambiar su estado. Pero olvidé la cláusula where.
Nunca olvidaré la sensación en la boca del estómago cuando vi (6834 hileras afectadas). Básicamente pasé toda la noche revisando los registros de eventos y averiguando el estado correcto de todos esos envíos. ¡Mierda!
Así que escribí un script (originalmente en awk) que iniciaría una transacción para cualquier actualización, y verificaría las filas afectadas antes de confirmar. Esto evitó sorpresas.
Así que ahora nunca hago actualizaciones desde línea de comandos sin pasar por un script como este. Aquí está (ahora en Python):
import sys
import subprocess as sp
pgm = "isql"
if len(sys.argv) == 1:
print "Usage: /nsql sql-string [rows-affected]"
sys.exit()
sql_str = sys.argv[1].upper()
max_rows_affected = 3
if len(sys.argv) > 2:
max_rows_affected = int(sys.argv[2])
if sql_str.startswith("UPDATE"):
sql_str = "BEGIN TRANSACTION//n" + sql_str
p1 = sp.Popen([pgm, sql_str],stdout=sp.PIPE,
shell=True)
(stdout, stderr) = p1.communicate()
print stdout
# example -> (33 rows affected)
affected = stdout.splitlines()[-1]
affected = affected.split()[0].lstrip(''('')
num_affected = int(affected)
if num_affected > max_rows_affected:
print "WARNING! ", num_affected,"rows were affected, rolling back..."
sql_str = "ROLLBACK TRANSACTION"
ret_code = sp.call([pgm, sql_str], shell=True)
else:
sql_str = "COMMIT TRANSACTION"
ret_code = sp.call([pgm, sql_str], shell=True)
else:
ret_code = sp.call([pgm, sql_str], shell=True)