A resposta principal a esta pergunta demonstra que cut
pode ser usado para tr
cortar com base em espaços repetidos com
< file tr -s ' ' | cut -d ' ' -f 8
Quero obter os controles remotos de vários repositórios Git em um diretório e estou tentando extrair os campos de URL remoto de cada um com o seguinte:
ls | xargs -I{} git -C {} remote -vv | sed -n 'p;n' | tr -s " " | cut -d ' ' -f1
No entanto, isso resulta (por exemplo) na seguinte saída, onde posso ver que dois espaços consecutivos (ponto de código Unicode 32) são retidos:
origin https://github.com/jik876/hifi-gan.git
origin https://github.com/NVIDIA/NeMo.git
origin https://github.com/NVIDIA/tacotron2.git
(Eu também uso xargs
with tr
)
A saída desejada é uma lista de URLs, como:
https://github.com/jik876/hifi-gan.git
https://github.com/NVIDIA/NeMo.git
https://github.com/NVIDIA/tacotron2.git
O que estou perdendo aqui?
Isso é uma tabulação, não dois espaços.
Você pode obter a mesma saída mais segura com um loop de shell iterando sobre os subdiretórios no diretório de trabalho atual que possui um
.git
diretório, depoiscut
o primeiro campo delimitado por espaço (para remover os rótulos(fetch)
e(push)
no final quegit
adiciona) e depois passaruniq
para mostre apenas uma única linha para cada URL remoto:O final
cut -f 2
isola os URLs retornando o segundo campo delimitado por tabulação.Levando em consideração que
awk
trata tabulações e espaços da mesma forma (a menos que você use um caractere ou padrão separador específico), podemos substituir o pipeline final por uma única invocação deawk
:Em vez de mexer com todos os espaços em branco, divisão de palavras e problemas de glob que o bash traz, você pode usar uma linguagem mais adequada ao trabalho... e uma que inclua um módulo de biblioteca para interagir com repositórios
bash
gittr
. Por exemplo, perl com o módulo Git::Raw .cut
xargs
Aqui está um exemplo muito simples de uma linha (embora seja importante notar que
Git::Raw
é capaz de muito mais do que isso e provavelmente seria melhor escrever um script perl independente que use o módulo):Adicionei novas linhas e recuo para facilitar a leitura. Funciona como está ou tudo comprimido em uma linha.
Em inglês, isso é:
Exemplo de saída. Executei o one-liner acima em um diretório que às vezes uso para clonar vários repositórios do github. Escrevi a linha única para imprimir o nome do diretório antes da lista de controles remotos pertencentes a esse repositório e uma linha em branco após cada diretório processado.
Nota:
Git::Raw
não está incluído no perl, ele precisa ser instalado comcpan
ou através de um pacote de distribuição (por exemplo, no Debian etc.apt-get install libgit-raw-perl
Outras distros provavelmente também o possuem). O módulo é um wrapper Perl em torno do libgit2 , portanto, instalá-lo manualmente com CPAN exigirágcc
a instalação da biblioteca de desenvolvimento e dos cabeçalhos do libgit2.Também vale a pena notar: mesmo sem
Git::Raw
analisar a saída dogit
perl (ou quase qualquer outra linguagem), será muito mais fácil e menos sujeito a erros do que fazê-lo no bash. Perl, em particular, foi projetado para correspondência e manipulação de strings; portanto, fazer o que você está tentando fazer no bash é trivial em perl.Aliás, se preferir
python
, você pode querer dar uma olhada no GitPython . No Debian etc, você pode instalá-lo comapt-get install python3-git
, e provavelmente também está empacotado para outras distros. Este não usalibgit2
, é um wrapper em torno dogit
comando, semelhante ao que você está tentando fazer no bash.De alguma forma, perdi isso ontem, mas o
libgit2
site diz que o pygit2 faz para o python o queGit::Raw
faz para o perl (ou seja, ele usa a biblioteca C libgit2 - portanto, será mais rápido do que bifurcargit
sempre que necessário e evita o risco de problemas de análise de saída). O pacote Debian épython3-pygit2
, e provavelmente também está empacotado para outras distros.