【问题标题】:Inserting a matched string from previous line to the current line using sed or awk使用 sed 或 awk 将匹配的字符串从前一行插入到当前行
【发布时间】:2011-10-22 04:55:12
【问题描述】:

我有一个 CSV 文件,它以半小时为单位显示链接的统计信息。链接名称仅出现在 00:00 行。

link1,0:00,0,0,0,0
,00:30,0,0,0,0
,01:00,0,0,0,0
,01:30,0,0,0,0
,02:00,0,0,0,0
,02:30,0,0,0,0
,03:00,0,0,0,0
,03:30,0,0,0,0
,23:30,0,0,0,0
....
....
link2,00:00,0,0,0,0

如何使用 sed 或 awk 将链接名称复制到每隔一行,直到链接名称不同?

【问题讨论】:

    标签: parsing csv sed awk


    【解决方案1】:

    您可以在纯 bash shell 中执行此操作,而无需启动新进程,这应该比使用 awk 或 sed 更快:

    IFS=","
    while read v1 v2; do
      if [[ $v1 != "" ]]; then
        link=$v1;
      fi
      printf "%s,%s\n" "$link" "$v2"
    done < file
    

    【讨论】:

      【解决方案2】:

      这是一个使用 awk 的更简单的工作,但如果你想使用 sed:

      sed -e '/^[^,]/{h;s/,.*//;x};/^,/{G;s/^\(.*\)\n\(.*\)/\2\1/}'
      

      下面是 sed 脚本文件格式的注释版本,可以使用 sed -f script 运行:

      # For lines not beginning with a ',', saves what precedes a ',' in the hold space and print the original line.
      /^[^,]/{
      h
      s/,.*//
      x}
      # For lines beginning with a ',', put what has been save in the hold space at the beginning of the pattern space and print.
      /^,/{
      G
      s/^\(.*\)\n\(.*\)/\2\1/}
      

      【讨论】:

        【解决方案3】:

        使用awk,只需跟踪最后看到的非空链接名称,并始终使用它。

        awk -F, -v OFS=, '$1 != "" { link=$1 } { $1 = link; print $0 }'
        

        省略省略号,得到:

        link1,0:00,0,0,0,0
        link1,00:30,0,0,0,0
        link1,01:00,0,0,0,0
        link1,01:30,0,0,0,0
        link1,02:00,0,0,0,0
        link1,02:30,0,0,0,0
        link1,03:00,0,0,0,0
        link1,03:30,0,0,0,0
        link1,23:30,0,0,0,0
        link2,00:00,0,0,0,0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-28
          • 2012-12-10
          相关资源
          最近更新 更多