读取文件,选择字段值并使其以制表符分隔

时间:2017-05-12 22:57:46

标签: shell

我有一个类似的文件:

Book: English  
Book: Latin  
Fruit: Orange  
Fruit: Apple  
Fruit: Grapes  

我只需要选取值,然后为{+ 1}}分隔类似字段,然后|,然后\t用第二个字段值分隔,依此类推。

例如,输出应为:

|

我尝试使用下面的代码但是,我没有得到我想要的。

English|Latin   <\t>   Orange|Apple|Grapes

请让我知道我哪里出错了。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

使用awk

试试这个:

$ awk -F': ' '{a[$1]=a[$1](length(a[$1])?"|":"")$2} END{printf "%s\t%s\n",a["Book"],a["Fruit"]}' file1.txt 
English|Latin   Orange|Apple|Grapes

工作原理

  • -F': '

    这告诉awk使用冒号空间作为字段分隔符。

  • a[$1]=a[$1](length(a[$1])?"|":"")$2

    对于我们从文件中读取的每一行,这告诉awk将第二个字段附加到第一个字段指定的键下的数组a。如果开头的数组值不为空,则在添加第二个字段之前附加|

    看起来很奇怪的部分(length(a[$1])?"|":"")三元声明。如果length(a[$1])求值为true(非零),则三元表达式返回字符串"|"。否则,它返回空字符串""。这样做的效果是在单词之间添加|,但在第一个单词之前 not

  • END{printf "%s\t%s\n",a["Book"],a["Fruit"]}

    我们读完文件后,会告诉awk打印图书列表,然后是标签\t,然后是水果列表,后跟换行符\n。< / p>

使用shell

a=
b=
while read key value
do
    case "$key" in
        'Book:') a="$a|$value";;
        "Fruit:") b="$b|$value";;
    esac
done <file1.txt
printf "%s\t%s\n" "${a#|}" "${b#|}"

这会产生输出:

English|Latin   Orange|Apple|Grapes