将键+n 值文本文件转换为 CSV 文件

将键+n 值文本文件转换为 CSV 文件

这个网站的新手,如果我提出这个问题很抱歉:

我有一个以下格式的文本文件:

file: abc
value: 123
value: 234
value: 567
file: def
value: 999
file: ghi
value: 123
value: 999

我的目标是编写一个 bash 脚本,将此文本转换为 CSV 格式,file其中每行重复该值。上面的数据需要看起来像这样:

abc,123
abc,234
abc,567
def,999
ghi,123
ghi,999

我一直在尝试,sed但不知道如何记住多行的文件名。我猜这可能会更容易,awk但我还没有“抓住”awk。

将不胜感激您的帮助!

答案1

只要找到这样的键,以下awk命令就将awk变量设置file为键的值file(键是该行的第一个字段,值是第二个字段)。如果当前行没有file键,则变量的当前值file与当前行的值一起输出。

$ awk -F ': ' 'BEGIN { OFS="," } $1 == "file" { file = $2; next } { print file, $2 }' file
abc,123
abc,234
abc,567
def,999
ghi,123
ghi,999

请注意,这不会尝试正确引用 CSV 的值,并且它假定没有值包含字段分隔符:(冒号+空格)。


sed

sed -n \
    -e '/^file: /  { s///; h; }' \
    -e '/^value: / { s///; G; s/\(.*\)\n\(.*\)/\2,\1/p; }' file

file:找到一行时,file:前缀字符串被剥离,剩余部分存储在保留空间中。

value:找到一行时,value:前缀字符串将被去除,保留空间中的文本将被附加到缓冲区的末尾,并以文字换行符作为分隔符。缓冲区中以换行符分隔的部分被交换(换行符用逗号替换)并输出。

结果和预期的一样。

这没有初始字符串后面的值key:不能包含冒号+空格的限制。同样,最终输出不会有任何特殊的 CSV 文本编码,因此包含嵌入逗号和双引号的字段会使 CSV 解析器感到困惑。


以下内容通过在原始文件中的每行之间添加空行来修改输入。这使得该文件成为有效的“XTAB”文件,并:作为键值分隔符。然后由 Miller ( ) 读取mlr,它了解 CSV 的特殊引用规则并且可以读取 XTAB 格式。

Miller 从输出中读取记录awk,并对数据执行“填充”操作file,将前一个file值分配给每条没有记录的记录。

随后的“过滤”操作会删除所有没有字段的记录value

然后输出的数据不带 CSV 标头。

awk '{ print; print "" }' file | 
mlr --ixtab --ips ': ' \
    --ocsv --headerless-csv-output \
    fill-down -f file then filter -x 'is_absent($value)'

我修改了测试数据,以表明即使输入包含逗号和引号,也能够正确生成完全兼容的 CSV 输出:

$ cat file
file: test: here's a test
value: this is, the value
value: another so called "value"
file: abc
value: 123
value: 234
value: 567
file: def
value: 999
file: ghi
value: 123
value: 999
$ awk '{ print; print "" }' file | mlr --ixtab --ips ': ' --ocsv --headerless-csv-output fill-down -f file then filter -x 'is_absent($value)'
"this is, the value",test: here's a test
"another so called ""value""",test: here's a test
123,abc
234,abc
567,abc
999,def
123,ghi
999,ghi

相关内容