使用sed或awk将匹配的字符串从上一行插入当前行

时间:2011-08-08 08:24:16

标签: parsing csv sed awk

我有一个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将链接名称复制到每个其他行,直到链接名称不同为止?

3 个答案:

答案 0 :(得分:1)

使用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

答案 1 :(得分:1)

使用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/}

答案 2 :(得分: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