Digamos que durante su jornada laboral se encuentra repetidamente la siguiente forma de salida en columna de algún comando en bash (en mi caso, al ejecutar svn st
en mi directorio de trabajo de Rails):
? changes.patch
M app/models/superman.rb
A app/models/superwoman.rb
Para trabajar con la salida de su comando, en este caso los nombres de archivo, se requiere algún tipo de análisis para que la segunda columna se pueda usar como entrada para el siguiente comando.
Lo que he estado haciendo es usar awk
para llegar a la segunda columna, por ejemplo, cuando quiero eliminar todos los archivos (no es que sea un caso de uso típico :), haría:
svn st | awk '{print $2}' | xargs rm
Como escribo mucho esto, una pregunta natural es: ¿hay una forma más corta (por lo tanto, más genial) de lograr esto en bash?
NOTA: Lo que estoy preguntando es esencialmente una pregunta de comando de shell a pesar de que mi ejemplo concreto está en mi flujo de trabajo svn. Si cree que el flujo de trabajo es tonto y sugiere un enfoque alternativo, probablemente no lo rechazaré, pero otros podrían hacerlo, ya que la pregunta aquí es realmente cómo obtener la salida del comando de la enésima columna en bash, de la manera más breve posible . Gracias :)
Respuestas:
Puede usar
cut
para acceder al segundo campo:Editar: Lo siento, no me di cuenta de que SVN no usa pestañas en su salida, por lo que es un poco inútil. Puede personalizar
cut
la salida, pero es un poco frágil, algo asícut -c 10-
funcionaría, pero el valor exacto dependerá de su configuración.Otra opción es algo como:
sed 's/.\s\+//'
fuente
cut -f2
con lasvn st
salida. Verás que no funciona.svn st
usaría pestañas en su salida. Después de algunas pruebas, parece que este no es el caso. Maldición.-d
permitir que esto funcione.cut -d" " -f2
.Para lograr lo mismo que:
usando solo bash puedes usar:
De acuerdo, no es más corto, pero es un poco más eficiente y maneja los espacios en blanco en sus nombres de archivo correctamente.
fuente
a
yb
cómo conseguirlos?a
representa la primera columna yb
representa las columnas restantes. Si desea imprimir la segunda columna, useread a b c;
y luego use enecho
lugar derm
. Utilicé esto para obtener un montón de procesos de ID que seguían un patrón grep, para poder interrumpirlos a todos.Me encontré en la misma situación y terminé agregando estos alias a mi
.profile
archivo:Lo que me permite escribir cosas como esta:
fuente
function c() { awk "{print \$$1}" }
Entonces puedes hacer:svn st | c 2 | xargs rm
Prueba el zsh. Admite alias de sufijo, por lo que puede definir X en su .zshrc para que sea
entonces puedes hacer:
Puede ir un paso más allá y definirlo para la enésima columna:
que generará la enésima columna del archivo "archivo". También puede hacer esto para la salida grep o menos salida. Esto es muy útil y una característica asesina de la zsh.
Puede ir un paso más allá y definir que D sea:
Ahora puedes escribir:
para eliminar todos los archivos mencionados en la primera columna del archivo "archivo".
Si conoce el bash, el zsh no es un gran cambio, excepto por algunas características nuevas.
HTH Chris
fuente
cut
opción. Simplemente no funciona en mi máquina usando la salida desvn st
. Intentasvn st | cut -d' ' -f2
solo ver qué sucede.Como parece no estar familiarizado con los scripts, aquí hay un ejemplo.
Si guarda esto
~/bin/x
y se asegura de que~/bin
esté en suPATH
(ahora eso es algo que puede y debe poner en su.bashrc
), tiene el comando más corto posible para extraer generalmente la columna n; x n.La secuencia de comandos debe realizar una verificación de errores adecuada y salir bajo fianza si se invoca con un argumento no numérico o el número incorrecto de argumentos, etc. pero la expansión de esta versión esencial básica estará en la unidad 102.
Tal vez desee extender el script para permitir un delimitador de columna diferente. Awk analiza de forma predeterminada la entrada en los campos en el espacio en blanco; para usar un delimitador diferente, use
-F ':'
where:
es el nuevo delimitador. Implementar esto como una opción para el script lo hace un poco más largo, así que lo dejo como un ejercicio para el lector.Uso
Dado un archivo
file
:Puede pasarlo a través de stdin (usando un inútil
cat
simplemente como marcador de posición para algo más útil);O proporcionarlo como un argumento para el script:
Aquí,
sh script.sh
se supone que el script se guarda comoscript.sh
en el directorio actual; si lo guarda con un nombre más útil en algún lugar de suPATH
y lo marca como ejecutable, como en las instrucciones anteriores, obviamente use el nombre útil en su lugar (y nosh
).fuente
awk -v col=$col ...
cat
ejemplo por razones histéricas (-:Parece que ya tienes una solución. Para facilitar las cosas, ¿por qué no simplemente poner su comando en un script bash (con un nombre corto) y simplemente ejecutarlo en lugar de escribir ese comando 'largo' cada vez?
fuente
.bashrc
? ¿Por qué lo abarrotaría con cosas no relacionadas con bash? Lo que hago es escribir scripts individuales para cada 'conjunto' de comandos y ponerlos todos en un~/scripts
directorio. Luego agregue todo~/scripts
a miPATH
para que pueda llamarlos por su nombre cuando los necesite.Si está de acuerdo con la selección manual de la columna, puede ser muy rápido usando pick :
Simplemente vaya a cualquier celda de la segunda columna, presione
c
y luego presioneenter
fuente
Tenga en cuenta que la ruta del archivo no tiene que estar en la segunda columna de salida de svn st. Por ejemplo, si modifica el archivo y modifica su propiedad, será la tercera columna.
Ver posibles ejemplos de salida en:
Salida de ejemplo:
Sugiero cortar los primeros 8 caracteres por:
Si desea estar 100% seguro y, por ejemplo, tratar con nombres de archivo elegantes con espacios en blanco al final, debe analizar la salida xml:
Por supuesto, es posible que desee utilizar un analizador XML real en lugar de grep / sed.
fuente