Parsing 使用sed或awk从前一行插入匹配字符串到当前行

Parsing 使用sed或awk从前一行插入匹配字符串到当前行,parsing,csv,sed,awk,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将链接名称复制到每一行,直到链接名称不同 使用aw

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

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

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

对于awk,这是一项更简单的工作,但如果您想使用sed:

sed -e '/^[^,]/{h;s/,.*//;x};/^,/{G;s/^\(.*\)\n\(.*\)/\2\1/}'
下面是sed脚本文件格式的注释版本,可与
sed-f脚本一起运行:

# 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/}

对于awk,这是一项更简单的工作,但如果您想使用sed:

sed -e '/^[^,]/{h;s/,.*//;x};/^,/{G;s/^\(.*\)\n\(.*\)/\2\1/}'
下面是sed脚本文件格式的注释版本,可与
sed-f脚本一起运行:

# 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/}

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

IFS=","
while read v1 v2; do
  if [[ $v1 != "" ]]; then
    link=$v1;
  fi
  printf "%s,%s\n" "$link" "$v2"
done < file
IFS=“,”
读取v1-v2时;做
如果[$v1!=“1]”;然后
link=$v1;
fi
printf“%s,%s\n”“$link”“$v2”
完成<文件

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

IFS=","
while read v1 v2; do
  if [[ $v1 != "" ]]; then
    link=$v1;
  fi
  printf "%s,%s\n" "$link" "$v2"
done < file
IFS=“,”
读取v1-v2时;做
如果[$v1!=“1]”;然后
link=$v1;
fi
printf“%s,%s\n”“$link”“$v2”
完成<文件