![需要将输出格式化为csv格式](https://linux22.com/image/111844/%E9%9C%80%E8%A6%81%E5%B0%86%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F%E5%8C%96%E4%B8%BAcsv%E6%A0%BC%E5%BC%8F.png)
这是 abc.txt 文件
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
需要 abc.csv 的以下格式的输出
NAME StartTime TotalElapsedTime Pool ThreadsReached
MARK 14:11:26.710583 0 10 0
MARK 14:11:26.710583 0 10 0
答案1
由于基本 CSV 格式假定逗号,
作为字段分隔符,因此使用以下 GNUsed方法:
sed -e '1iNAME,StartTime,TotalElapsedTime,Pool,ThreadsReached' -e 's/[^=]*="\([^"]*\)"/\1,/g; s/,$//g' file
输出:
NAME,StartTime,TotalElapsedTime,Pool,ThreadsReached
MARK,14:11:26.710583,0,10,0
MARK,14:11:26.710583,0,10,0
1i
- 插入物标头文件第一行之前的行
s/[^=]*="\([^"]*\)"/\1,/g
- 提取所有属性值
答案2
while IFS= read -r l; do
set -f; IFS==; set -- $l; shift; N=$#
for arg
do
set -- ${1+"$@"} "$(expr " $arg" : ' "\(.*\)"')"
done
shift "$N"; IFS=,; echo "$*"
done < abc.txt
while IFS= read -r l; do
set -f; IFS==; set -- $l; shift
while case ${#} in 1 ) break ;; esac; do
expr " $1" : ' "\(.*\)"'
shift
done | tr \\n ,; expr " $*" : '.*"\(.*\)"'
done < abc.txt
perl -lne '$,=",";
print /(?:^|\h)\K[^=]*/g if $. == 1;
print /="([^"]*)"/g;
' abc.txt
说明
- 在 Perl 代码中,从第一行开始,我们通过正则表达式提取字段名称,该正则表达式被读取为获取左侧显示水平空白或行开头的字符
/(?:^|\h)\K[^=]*/g
运行。然后使用设置为逗号来打印这些内容。non=
\h
^
OFS
$,
- 对于所有行(也包括第一行),我们通过正则表达式提取字段值,
/="([^"]*)"/g
该正则表达式将被读取为提取用双引号值括起来的字符串(假设没有转义双引号),该字符串与其上的等号相邻左边。然后将这些值的集合stdout
与OFS
. - 在循环解决方案的情况下
while
,我们首先按原样读入该行,不进行分词。然后我们将 IFS 设置为 an=
并拒绝第一个字段。现在所有字段都将具有以下格式,"..."...
然后我们使用该expr
实用程序充实双引号内的值并将它们放在$@
数组中。在循环结束时,for
我们删除原始元素($N
),然后剩下的就是我们想要的。最后通过将 IFS 设置为逗号并展开,将它们通过逗号连接在一起$*
。