I'm trying to build a cherry-picking UI for Git. The output of git log produces lines like this:

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

I want to pass this as arguments to dialog for a checklist:

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

Unfortunately, I can't figure out how to pass the output of git-log as arguments to dialog.

Further arguments to dialog are 3-tuples, such as <commit> <message> <selected>, hence the formatting of git-log above. I can't seem to figure out the expansion.

Some tests:

$ 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

Update: The correct result for $args[2] should be Alice, 78 minutes ago - Thumbnails are now 300x300.

  • The reason the last one doesn't work is that the shell treats " in input as a special case to enclose a string that might contain spaces. This behavior is lost when the quotes are read from a program's output — similar to writing \" on the command line. – Daniel Beck Nov 8 '11 at 20:37
  • It isn't clear to me, what the correct result would be here. – Zoredache Nov 8 '11 at 20:53
  • @Zoredache Oops, updated. – a paid nerd Nov 8 '11 at 21:09

You can use the following code to replace all spaces in a line except the first and the last by a non-breaking space character, which the shell doesn't think of as whitespace.

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

To also remove the quotation marks (all quotation marks, unfortunately), use:

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

To verify that it works:

$ awk '…' temp | cut -d" " -f1
$ 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 breaks my answer. That space character between quotation marks in x=x " " $i is supposed to be 0xC2A0, Unicode code point U+00A0.


a little change to IFS, and some stripping of whitespace, and you can pull the arguments, but it's not exactly a one-liner.


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

# save the current IFS, to restore

# set the new IFS to " marks
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]"

# reset the IFS

From there your line is split, maintaining the quoted middle field, and you can do whatever you need with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.