awk获取下一行列的值并将其添加到shellscript中的当前行

awk to get value for a column of next line and add it to the current line in shellscript

我有一个 csv 文件让我们说行

cat lines
1:abc
6:def
17:ghi
21:tyu

我想实现这样的目标

1:6:abc
6:17:def
17:21:ghi
21::tyu

尝试了下面的代码没有用

awk 'BEGIN{FS=OFS=":"}NR>1{nln=;cl=}NR>0{print ,nln,}' lines
1::abc
6:6:def
17:17:ghi
21:21:tyu

你能帮忙吗?

第一个解决方案: 这是一个tac + awk + tac解决方案。仅使用显示的示例编写和测试。

tac Input_file | 
awk '
BEGIN{
  FS=OFS=":"
}
{
  prev=(prev?=prev OFS :=OFS )
}
{
  prev=
}
1
' | tac

说明:为以上代码添加详细说明。

tac Input_file |     ##Printing lines from bottom to top of Input_file.
awk '                ##Getting input from previous command as input to awk.
BEGIN{               ##Starting BEGIN section from here.
  FS=OFS=":"         ##Setting FS and OFS as colon here.
}
{
  prev=(prev?=prev OFS :=OFS )  ##Creating prev if previous NOT NULL then add its value prior to  with prev OFS else add OFS  in it.
}
{
  prev=            ##Setting prev to  value here.
}
1                    ##printing current line here.
' | tac              ##Sending awk output to tac to make it in actual sequence.


第二个解决方案: 仅添加 awk 解决方案,并向其传递 2 次 Input_file。

awk '
BEGIN{
  FS=OFS=":"
}
FNR==NR{
  if(FNR>1){
    arr[FNR-1]=
  }
  next
}
{
  =(FNR in arr)?(arr[FNR] OFS ):OFS 
}
1
'  Input_file  Input_file

这是一个潜在的 AWK 解决方案:

cat lines
1:abc
6:def
17:ghi
21:tyu

awk -F":" '{num[NR]=; letters[NR]=}; END{for(i=1;i<=NR;i++) print num[i] ":" num[i + 1] ":" letters[i]}' lines
1:6:abc
6:17:def
17:21:ghi
21::tyu

格式化:

awk '
BEGIN {FS=OFS=":"}
{
  num[NR] = ;
  letters[NR] = 
}
END {for (i = 1; i <= NR; i++)
        print num[i], num[i + 1], letters[i]
}
' lines
1:6:abc
6:17:def
17:21:ghi
21::tyu

基本上这是你的解决方案,但我改变了代码块的顺序并添加了 END 块来输出最后一条记录,你很接近:

awk 'BEGIN{FS=OFS=":"}FNR>1{print p,,q}{p=;q=}END{print p,"",q}' file

解释:

$ awk 'BEGIN {
    FS=OFS=":"    # delims
}
FNR>1 {           # all but the first record 
    print p,,q  # output  and  from the previous round
}
{
    p=          # store for the next round
    q=
}
END {             # gotta output the last record in the END
    print p,"",q  # "" feels like cheating
}' file

输出:

1:6:abc
6:17:def
17:21:ghi
21::tyu