bash - Expansão de parâmetros da matriz em argumentos

1

Estou tentando criar uma interface do usuário para o Git. A saída de git log produz linhas como esta:

e9dfe65  "Alice, 78 minutes ago - Thumbnails are now 300x300" no
3b780ba  "Bob, 3 hours ago - new intro page" no
7ba8120  "Charles, 20 hours ago - add cutoff date for widget timing" no

Eu quero passar isso como argumentos para o diálogo para uma lista de verificação:

dialog --checklist "Choose commits to cherry-pick:" 0 0 0 ...

Infelizmente, não consigo descobrir como passar a saída do git-log como argumentos para o diálogo.

Outros argumentos para o diálogo são 3-tuplas, como <commit> <message> <selected> , daí a formatação do git-log acima. Eu não consigo descobrir a expansão.

Alguns testes:

$ git log ... >temp

$ args="$(cat temp)" ; echo $args[2]
9                                    // WRONG

$ args='cat temp' ; echo $args[2]              
9                                    // WRONG

$ args=('cat temp') ; echo $args[2] 
"Alice,                              // WRONG

Atualização: O resultado correto para $args[2] deve ser Alice, 78 minutes ago - Thumbnails are now 300x300 .

    
por a paid nerd 08.11.2011 / 21:26

2 respostas

2

Você pode usar o seguinte código para substituir todos os espaços em uma linha, exceto o primeiro e o último por um caractere de espaço sem quebra, que o shell não considera como espaço em branco.

awk '{ x=$2; for(i=3;i<NF;i++){x=x " " $i }; print $1 " " x " " $NF }' temp

Para remover também as aspas (todas as aspas, infelizmente), use:

awk '{ gsub(/"/, ""); x=$2; for(i=3;i<NF;i++){x=x " " $i }; print $1 " " x " " $NF }' temp

Para verificar se funciona:

$ awk '…' temp | cut -d" " -f1
e9dfe65
3b780ba
7ba8120
$ awk '…' temp | cut -d" " -f2
Alice, 78 minutes ago - Thumbnails are now 300x300
Bob, 3 hours ago - new intro page
Charles, 20 hours ago - add cutoff date for widget timing

Super User quebra minha resposta. Esse caractere de espaço entre aspas em x=x " " $i deve ser 0xC2A0 , ponto de código Unicode U+00A0 .

    
por 08.11.2011 / 22:18
1

uma pequena mudança no IFS, e alguns espaços em branco, e você pode puxar os argumentos, mas não é exatamente um verso.

#!/usr/bin/bash

# log format:
# 
# $one  $two               $three
# nnnnn "mmmm mmm mmm mmm" zzzzzz

# save the current IFS, to restore
OLDIFS=$IFS

# set the new IFS to " marks
IFS='"'
cat /tmp/log | while read one two three; do
        # strip the whitespace from $one and $three
        one="$(echo $one | sed -e 's/ //g')"
        three="$(echo $one | sed -e 's/ //g')"
        # print in brackets to see what falls where
        echo "[$one]: [$two] [$three]"
done

# reset the IFS
IFS=$OLDIFS

A partir daí, sua linha é dividida, mantendo o campo do meio entre aspas, e você pode fazer o que precisar com ela.

    
por 08.11.2011 / 21:53

Tags