【问题标题】:How to parse contents of a file using sed/awk?如何使用 sed/awk 解析文件的内容?
【发布时间】:2016-05-26 00:41:04
【问题描述】:

我的输入文件具有以下格式的内容,其中每一列由“空格”分隔

string1<space>string2<space>string3<space>YYYY-mm-dd<space>hh:mm:ss.SSS<space>string4<space>10:1234567890<space>0e:Apple 1.2.3.4<space><space>string5<space>HEX  

“0e:Apple 1.2.3.4”之后有 2 个“空格”,因为该字段/列中没有第 14 位数字。整个“0e:Apple 1.2.3.4space”被视为该列的单个值。

在第 7 列中,10: 表示以下字符串中的字符数。

在第 8 列中,0e: 表示十六进制值 14。因此,十六进制值提到了后面字符串中的字符数。

喜欢:

"0e:Apple 1.2.3.4 "--> this is the actual value in 8th column without " "  
    (I've mentioned " " to show that the 14th digit is empty)  

It's counted as  
0e:A p p l e   1 . 2 .   3  . 4    
   | | | | | | | | | |   |  | | |  
   1 2 3 4 5 6 7 8 9 10 11 12 1314  

让我们将输入文件的第一行视为:

string1 string2 string3 yyyy-mm-dd 23:50:45.999 string4 10:1234567890 0e:Apple 1.2.3.4  string5 001e  

地点:

  • string1 是第一列的值
  • string2 是第二列的值
  • string3 是第三列的值
  • yyyy-mm-dd 第 4 次
  • 23:50:50.999 第 5 名
  • string3 第 6 名
  • 10:1234567890 in 7 //最后没有空格,因为它有10位数字
  • 0e:Apple 1.2.3.4 在第 8 个 // 末尾的空格
  • string5在第9
  • 001e 第十名

预期输出:

string1,string2,string3,yyyy-mm dd,23:50:50.999,string3,1234567890,Apple_1.2.3.4,string5,30  

要求:

  1. 消除第 7 列和第 8 列的计数 (10: & 0e:)
  2. Apple1.2.3.4 的空格 b/w 应替换为 "_"
  3. 最后一列的十六进制值应转换为十进制值。
  4. "," 替换列之间的“空格”
  5. 我在这里只在第 10 列使用了十六进制值。如果它在多个列中怎么办?有什么方法可以将其转换为特定于某些列?

我试过用这个:

$ cat input.txt |sed 's/[a-z0-9].*://g'  

输出如下:

string1,string2,string3,yyyy-mm-dd,45.999,string4,1234567890,Apple,1.2.3.4,,string5,001e  

【问题讨论】:

  • 你确定你的意思是preceding吗?
  • 所以,基本上,您并没有尝试自己做任何事情。您发布的sed 示例显然不适合您的要求(可能第一个除外)。而sed 对于您想要做的事情来说还不够强大。 sed 大师可能会写一个两百行的程序来解决这个问题,但这会非常困难。
  • @MichaelVehrs 我的错。它是以下字符串。编辑它。谢谢! :)
  • @MichaelVehrs 是的。我的脚本只是第一个。我也可以用其他脚本做 4。但不确定如何处理 2,3 和 5。我们可以用 awk 来做吗? (逐个字符串解析?)

标签: bash awk sed grep


【解决方案1】:

这将在您的示例输入中执行您想要的操作:

awk -F "[ ]" '{sub(/.*:/, "", $7) sub(/.*:/, "", $8); printf "%s,%s,%s,%s,%s,%s,%s,%s_%s,%s,%s,%d\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, "0x"$12}' input.txt

部分说明:

awk printf 允许您指定输出格式,因此您可以手动指定要使用, 分隔的字段以及要使用_ 分隔的字段。

-F "[ ]" 强制字段分隔符为单个空格,以便它知道两个单个空格之间有一个空字段。默认行为是允许多个空格作为单个分隔符,根据问题,这不是您想要的。

sub 函数允许您进行正则表达式替换,在这种情况下删除字段 7 和 8 中的 ..: 前缀。

对于字段 12,我们告诉 printf 输出为数字 (%d),并将前缀为 0x 的字符串作为输入,以便将其解释为十六进制。

注意:如果您并不总是希望输出为$8_$9,那么您实际上需要解析十六进制前缀并计算字符数以确定字段的结束位置.如果是这样的话,我个人更喜欢用别的东西写整个东西,例如蟒蛇。

【讨论】:

    猜你喜欢
    • 2015-01-12
    • 1970-01-01
    • 2018-03-31
    • 2017-09-19
    • 2013-02-06
    • 2022-11-30
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多