awk 中两个分隔符的问题

awk 中两个分隔符的问题

我正在尝试创建一个显示分支名称和描述的 git 别名。没有专门的命令或开关来获取分支的描述;必须从配置中暂停它。不过,我想获得所有分支及其描述的列表(如果有的话)。

人们可以获得一种“原始数据”,如下所示:

$ git config -l
core.symlinks=false
core.autocrlf=false
core.fscache=true
color.diff=auto

所以我感兴趣的条目如下所示:

branch.featureA.description=Mail templates
branch.featureB.description=Something else

我可以通过这个管道得到:git config -l | grep description | grep \^branch.对于我想要的输出,我想要这个:

featureA Mail templates
featureB Something else

因此,表达这一点的一种方法是,我想要句号之后的第二个“列”,以及等号之后的第一个“列”。或者,我想要.branchname..description=删除。我不确定最好的方法,但我尝试将awk字符串视为列。我可以用不同的分隔符得到我想要的部分:

$ git config -l | grep description | grep \^branch. | awk -F '.' '{ print $2 }'
featureA
featureB

$ git config -l | grep description | grep \^branch. | awk -F '=' '{ print $2 }'
Mail Templates
Something else

然而,尝试组合两个分隔符似乎不起作用:

$ git config -l | grep description | grep \^branch. | awk -F '.=' '{ print $2 }'
Mail templates
Something else

如何从字符串中解析出我想要的数据?

答案1

我可能会用sed这个:

sed -n '/^branch/{ s/[^.]*\.//; s/\.[^=]*=/ /p; }'

这捕获以字符串开头的任何行branch以及每一行

  1. 删除第一个点之前的所有内容,然后
  2. =用空格替换从第一个剩余点到第一个字符(包括第一个字符)的所有内容。

然后打印修改后的行。任何其他行都将被丢弃。


awk

awk -F '=' '/^branch/ { split($1, a, "."); print a[2], $2 }'

这将输入视为由 分隔=,然后将第一部分分割为点。然后,它打印第二个点分隔字符串以及=.

如果该行包含多个,则此操作将会失败=(第二个之后的位=将丢失)。

答案2

这是另一种方法sed

git config -l | sed -n 's/^branch[.]\(.*\)[.]description=/\1 /p'

说明:打印“branch.(something).description=(something)”形式的所有行,(something) 之间只有一个空格。这可以-n防止它自动打印与此模式不匹配的行。

答案3

你可以用 bash 来做到这一点:

while IFS="=" read key value; do 
    if [[ key == branch.*.description ]]; then
        branch=${key#branch.}        # remove "branch." prefix
        branch=${key%.description}   # remove ".description" suffix
        echo "$branch $value" 
    fi
done < <(git config -l)

我故意将这条线“分割”两次:第一次相等然后在点上。 “值”显然可以有点,所以我想完全控制单词分割。

相关内容