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 sten 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 awkpara 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
cutpara 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
cutla 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 -f2con lasvn stsalida. Verás que no funciona.svn stusaría pestañas en su salida. Después de algunas pruebas, parece que este no es el caso. Maldición.-dpermitir 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
aybcómo conseguirlos?arepresenta la primera columna ybrepresenta las columnas restantes. Si desea imprimir la segunda columna, useread a b c;y luego use enecholugar 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
.profilearchivo:Lo que me permite escribir cosas como esta:
fuente
function c() { awk "{print \$$1}" }Entonces puedes hacer:svn st | c 2 | xargs rmPrueba 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
cutopción. Simplemente no funciona en mi máquina usando la salida desvn st. Intentasvn st | cut -d' ' -f2solo ver qué sucede.Como parece no estar familiarizado con los scripts, aquí hay un ejemplo.
Si guarda esto
~/bin/xy se asegura de que~/binesté 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
catsimplemente como marcador de posición para algo más útil);O proporcionarlo como un argumento para el script:
Aquí,
sh script.shse supone que el script se guarda comoscript.shen el directorio actual; si lo guarda con un nombre más útil en algún lugar de suPATHy lo marca como ejecutable, como en las instrucciones anteriores, obviamente use el nombre útil en su lugar (y nosh).fuente
awk -v col=$col ...catejemplo 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~/scriptsdirectorio. Luego agregue todo~/scriptsa miPATHpara 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
cy luego presioneenterfuente
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