【问题标题】:CSV data multiple level parsing Shell scriptCSV数据多级解析Shell脚本
【发布时间】:2020-03-11 11:42:15
【问题描述】:

您好,我有一个以下格式的 CSV 数据

ColumnHeader1,ColumnHeader2,ColumnHeader3
valcol1p1,name=testapp1 environment=dev coldata=My_Test_Logs @$ 192.168.1.1 @$ r1 @$ r2 @$ POST API ,valcol3p1
valcol1p1,name=testapp2 environment=qa coldata=My_Test_Logs @$ 192.168.1.1 @$ r1 @$ r2 @$ GET API ,valcol3p1 

我需要在 My_Test_Logs 之后提取 ColumnHeader2 列中的数据,并在分隔符“@$”之后解析数据。所以对于每个 csv 行,我会得到 4 个值。 我需要将它们与相同的分隔符值“@$”连接起来并放在 CSV 中。

输出会是这样的

现在我已经部分解决了。

喜欢获取ColumnHeader2列数据

awk -F "\"*,\"*" '{print $2}' Mytest.csv

或使用多个字符分隔符仅取前 x 个字段:

awk -F"[@][$]" '{print $1,$2,$3,$4}' Mytest1.csv
其中 MyTest1 包含提取的 Columnheader2 数据的输出

但是提取然后连接的整个逻辑一起给出了一些问题。有人可以在这里提供帮助吗。我需要一个脚本来处理我的 CSV 并将结果写入另一个 csv,而不是在两者之间使用多个 csv 或文本输出?

【问题讨论】:

  • 该样本数据的输出应该是什么?
  • 类似这样的东西..仅显示一行,但实际上它将是来自 csv 192.168.1.1 @$ r1 @$ r2 @$ GET API 的所有行
  • 请编辑示例输出到问题的可读性。
  • 你在正确的轨道上,你只需要设置OFS变量awk -F ',| *@[$] *' -v OFS='@$' '{print $3,$4,$5}' sample.txt(这结合了两个awk命令)
  • @pythonNinja 好吧,我不打算写答案。但是,你去stackoverflow.com/a/60636646/939457

标签: linux bash csv delimiter fileparsing


【解决方案1】:

这应该满足你的两个要求:

awk -F',| *@[$] *' -v OFS='@$' -e 'NR==1 {print "outCol1","outCol2","outcol3"}; NR > 1 { print $3,$4,$5}' sample.txt

outCol1@$outCol2@$outcol3
192.168.1.1@$r1@$r2
192.168.1.1@$r1@$r2
  • -F',|@[$]' - field separator is a regular expression in awk, this will match both,and@$, and also trim the spaces around@$`
  • -v OFS='@$' - 输出的默认字段分隔符是空格,这会将其设置为 '@$'
  • NR == 1 {print "outCol1","outCol2","outcol3"} - 第一行打印新标题
  • NR > 1 { print $3,$4,$5} - 其余行打印字段 $3,$4,$5

注意:这假定在 CSV 的其余部分中没有 ,@$ 转义,否则您应该使用适当的 CSV 解析器。

【讨论】:

  • 感谢@Sorin 这工作。很好的解释以及
【解决方案2】:

与大多数 bash 工具不同,这将以安全的方式处理 CSV。

#!/usr/local/bin/python3

import csv
csvr = csv.reader(open('your_file.csv'), delimiter = ",")

results = []
index=0
for row in csvr:
    if index == 0:
        index = index +1
        continue
    results.append(row[1].split('@$')[1:])

for row in results:
    print(",".join(row))

输出:

 192.168.1.1 , r1 , r2 , POST API 
 192.168.1.1 , r1 , r2 , GET API

希望对你有帮助!

【讨论】:

  • 我有一个多字符分隔符 "@$"..TypeError: "delimiter" must be a 1-character string
  • @pythonNinja 使用 Python3 还是 Python 2?
  • 我正在使用python3
  • @pythonNinja 这很奇怪。它应该工作得很好。它对我有用。另外,看看这个:repl.it/repls/MetallicCloseKernel
【解决方案3】:

使用 awk 在My_Test_Logs 处拆分:

$ awk -F, '{print (split($2,a,/My_Test_Logs /)>1?a[2]:a[1])}' file

输出:

ColumnHeader2
@$ 192.168.1.1 @$ r1 @$ r2 @$ POST API 
@$ 192.168.1.1 @$ r1 @$ r2 @$ GET API 

更新:

鉴于更好的预期输出:

$ awk -F, '{print (split($2,a,/ /)>1?a[5] OFS a[6] OFS a[7] OFS a[8] OFS a[9] OFS a[10] OFS a[11] OFS a[12]:a[1])}' file

现在输出:

ColumnHeader2
192.168.1.1 @$ r1 @$ r2 @$ POST API
192.168.1.1 @$ r1 @$ r2 @$ GET API

【讨论】:

  • 这不起作用,因为缺少分隔符..我这样编辑它:---- awk -F"[@][$]" '{print (split($2,a ,/My_Test_Logs />/)>1?a[2]:a[1])}' MyTest.csv
  • 之后我只是将第一列作为输出,而不是所有列都再次带有“@$”间距...
  • 192.168.1.1 192.168.1.1
  • 感谢@james,这也是一个很好的替代解决方案。更新让事情变得清晰
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
相关资源
最近更新 更多