Digamos que, durante seu dia de trabalho, você encontre repetidamente a seguinte forma de saída em colunas de algum comando no bash (no meu caso, executando svn st
no meu diretório de trabalho do Rails):
? changes.patch
M app/models/superman.rb
A app/models/superwoman.rb
para trabalhar com a saída do seu comando - nesse caso, os nomes dos arquivos - é necessário algum tipo de análise para que a segunda coluna possa ser usada como entrada para o próximo comando.
O que eu tenho feito é usar awk
para chegar à segunda coluna, por exemplo, quando eu quero remover todos os arquivos (não que isso seja um típico caso de usuário :), eu faria:
svn st | awk '{print $2}' | xargs rm
Como eu digito muito isso, uma pergunta natural é: existe uma maneira mais curta (portanto mais fria) de fazer isso no bash?
NOTA: O que estou perguntando é essencialmente uma pergunta de comando do shell, mesmo que meu exemplo concreto esteja no meu fluxo de trabalho svn. Se você achar que o fluxo de trabalho é tolo e sugerir uma abordagem alternativa, provavelmente não votarei contra você, mas outros podem, já que a questão aqui é realmente como obter o comando da n-ésima coluna no bash, da maneira mais curta possível . Obrigado :)
Respostas:
Você pode usar
cut
para acessar o segundo campo:Edit: Desculpe, não percebi que o SVN não usa guias em sua saída, então isso é um pouco inútil. Você pode personalizar
cut
a saída, mas é um pouco frágil - algo comocut -c 10-
funcionaria, mas o valor exato dependerá da sua configuração.Outra opção é algo como:
sed 's/.\s\+//'
fonte
cut -f2
com asvn st
saída. Você verá que não funciona.svn st
usaria tabulações em sua saída. Após alguns testes, parece que esse não é o caso. Droga.-d
permitir que isso funcione.cut -d" " -f2
.Para realizar o mesmo que:
usando apenas o bash, você pode usar:
Concedido, não é mais curto, mas é um pouco mais eficiente e lida com o espaço em branco nos seus nomes de arquivos corretamente.
fonte
a
eb
como obtê-los?a
representa a primeira coluna eb
as colunas restantes. Se você deseja imprimir a segunda coluna, useread a b c;
e use emecho
vez derm
. Eu usei isso para obter vários processos de IDs que seguiam um padrão grep, para que eu pudesse interromper todos eles.Eu me encontrei na mesma situação e acabei adicionando esses aliases ao meu
.profile
arquivo:O que me permite escrever coisas assim:
fonte
function c() { awk "{print \$$1}" }
Então você pode fazer:svn st | c 2 | xargs rm
Experimente o zsh. Ele suporta alias de sufixo, para que você possa definir o X no seu .zshrc como
então você pode fazer:
Você pode dar um passo adiante e defini-lo para a enésima coluna:
que produzirá a enésima coluna do arquivo "file". Você também pode fazer isso para saída grep ou menos saídas. Isso é muito útil e um recurso matador do zsh.
Você pode dar um passo adiante e definir D como:
Agora você pode digitar:
para excluir todos os arquivos mencionados na primeira coluna do arquivo "arquivo".
Se você conhece o bash, o zsh não muda muito, exceto por alguns novos recursos.
HTH Chris
fonte
cut
opção. Simplesmente não funciona na minha máquina usando a saída desvn st
. Tentesvn st | cut -d' ' -f2
apenas ver o que acontece.Como você não está familiarizado com os scripts, aqui está um exemplo.
Se você salvar isso
~/bin/x
e garantir que~/bin
está no seuPATH
(agora isso é algo que você pode e deve colocar no seu.bashrc
), você possui o comando mais curto possível para extrair geralmente a coluna n; x n.O script deve executar uma verificação de erro e salvá-lo adequadamente, se invocado com um argumento não numérico ou com um número incorreto de argumentos, etc; mas a expansão dessa versão essencial básica estará na unidade 102.
Talvez você queira estender o script para permitir um delimitador de coluna diferente. O awk, por padrão, analisa a entrada em campos no espaço em branco; Para usar um delimitador diferente, use
-F ':'
where:
é o novo delimitador. Implementar isso como uma opção para o script o torna um pouco mais longo, então estou deixando isso como um exercício para o leitor.Uso
Dado um arquivo
file
:Você pode passá-lo via stdin (usando um inútil
cat
apenas como espaço reservado para algo mais útil);Ou forneça isso como argumento para o script:
Aqui,
sh script.sh
está assumindo que o script é salvo comoscript.sh
no diretório atual; se você o salvar com um nome mais útil em algum lugar do seuPATH
e o marcar como executável, como nas instruções acima, obviamente use o nome útil (e nãosh
).fonte
awk -v col=$col ...
cat
exemplo por razões histéricas (-:Parece que você já tem uma solução. Para facilitar as coisas, por que não colocar seu comando em um script bash (com um nome abreviado) e simplesmente executá-lo em vez de digitar o comando 'long' toda vez?
fonte
.bashrc
? Por que você iria desordenar com coisas não relacionadas ao bash. O que faço é escrever scripts individuais para cada 'conjunto' de comandos e colocá-los todos em um~/scripts
diretório. Em seguida, adicione o todo~/scripts
ao meu,PATH
para que eu possa chamá-los pelo nome quando precisar deles.Se você concorda com a seleção manual da coluna, pode ser muito rápido usando pick :
Basta ir a qualquer célula da 2ª coluna, pressionar
c
e depois pressionarenter
fonte
Observe que esse caminho do arquivo não precisa estar na segunda coluna da saída svn st. Por exemplo, se você modificar o arquivo e modificar sua propriedade, será a terceira coluna.
Veja possíveis exemplos de saída em:
Exemplo de saída:
Sugiro cortar os 8 primeiros caracteres da seguinte maneira:
Se você deseja ter 100% de certeza e lidar com nomes de arquivos sofisticados com espaço em branco no final, por exemplo, é necessário analisar a saída xml:
Obviamente, você pode querer usar algum analisador XML real em vez de grep / sed.
fonte