【问题标题】:Reformat a long file using awk/sed使用 awk/sed 重新格式化长文件
【发布时间】:2017-07-26 23:54:58
【问题描述】:

我有一个很长的文件。文件内容如下:

myserver1
kernel_version
os

myserver2
kernel_version
os

myserver3
kernel_version
os
...

每个主机有 10.000 多个条目和 3 个条目。主机名、内核版本和操作系统版本。

我想要一个类似的输出:

myserver1, kernel_version, os
myserver2, kernel_version, os
myserver3, kernel_version, os
...

相反。那么提供此输出的最佳 awk/sed 命令是什么?

【问题讨论】:

  • 您需要添加自己的尝试来解决问题...就像我在您过去提出的问题中看到的那样...

标签: linux shell awk sed grep


【解决方案1】:

使用 sed:

$ sed '/^$/d;N;N;s/\n/, /g' infile                                  
myserver1, kernel_version, os                              
myserver2, kernel_version, os                              
myserver3, kernel_version, os

它的工作原理如下:

/^$/d       # Delete line if empty (skips rest of commands)
N           # Append second line to pattern space
N           # Append third line to pattern space
s/\n/, /g   # Replace newlines by comma and a blank

如果您希望跳过的行的标准不是“空行”而是其行号(4、8、12...),您可以替换第一个命令(这是一个 GNU 扩展):

sed '4~4d;N;N;s/\n/, /g' infile

【讨论】:

    【解决方案2】:

    你也可以使用paste:

    paste -d ',,\0' - - - - <file
    

    【讨论】:

    • 值得注意的是,这也适用于非空白“分隔符”行。
    • 这很优雅,但请注意,它实际上并没有跳过空行,而是将其附加到每条记录中。
    • 您可以改用paste -sd',,\0\n' file,但, 之间仍然不会有任何空格
    【解决方案3】:

    你可以使用:

    awk 'BEGIN{RS="";OFS=", "} {print $1,$2,$3}' data.txt
    

    将记录分隔符定义为空行,输出字段分隔符 (OFS) 为 ", "

    你也可以使用:

    awk 'BEGIN{RS="";OFS=", "} {$1=$1; print $0}' data.txt
    

    $1=$1 强制重构记录,参见this

    【讨论】:

    • 第一个命令只显示第一个主机的属性。像:myserver1, kernel_version, os 但不是其他主机。第二个,它将所有条目显示在一行中,例如:myserver1, kernel_version, os, myserver2, kernel_version, os, myserver3, kernel version, os
    • @JavaRed 在这种情况下,您在条目之间没有空行,并且您显示的输入样本是错误的......简单的pr -3ats', ' data.txt 会为您工作
    【解决方案4】:

    虽然 AWK/SED 可以帮助您执行此任务,但更好的方法是使用 Python,假设您正在使用的 *NIX 系统已安装它来处理此数据。

    您可以在 python 中使用以下内容很容易地处理它:

    import csv
    
    output_file = csv.writer(open("/path/to/output/file","w"))
    
    column_num = 3 # number of columns in your end-state data
    with open("</path/to/your/input/file>","r") as input:
      row = []
      iteration_counter = 0
      for line in input:
        iteration_counter += 1
        stripped = line.strip() # to remove the newlines (\n)
        if iteration_counter <= column_num:
          row.append(stripped)
        else:
          iteration_counter = 0 # reset the counter to 0
          output_writer.writerow(row) # output the list as a csv row
          row = [] # clear the row list to nothing
          iteration_counter += 1
          row.append(stripped)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 2015-11-09
      • 1970-01-01
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      相关资源
      最近更新 更多