如何在 awk 命令中复制行? (首选 ksh 脚本)

如何在 awk 命令中复制行? (首选 ksh 脚本)

我有以下索引文件

 key1|1|1001
 key1|1|2001
 key2|2|3001
 key2|2|4001
 using this index file, I have to update my main file
 key1|1000|2000|3000|4000
 key2|1000|2000|3000|4000

 The expected output should be
 key1|1001|2000|3000|4000
 key1|2001|2000|3000|4000
 key2|1000|3001|3000|4000
 key2|1000|4001|3000|4000

但我下面的 script.awk 并没有复制主文件中的键,而是不断覆盖相应索引中的值。脚本有什么问题? awk -f script.awk index.txt main.txt

    #!/bin/awk
BEGIN {
    FS = "|"
}
( NR == FNR ) {
    lookup[toupper($1)] = $0
}

( NR > FNR ) {
    key = toupper($1)
    split(lookup[key], replacements, "|")
    for (i = 1; i <= NF; i++)
        col[i] = $i;
    for (i=1; i <= NF; i=i+1){
    j=replacements[i]
    col[j] = replacements[i+1]
    }
    for (i = 1; i <= NF; i++)
        printf "%s|", col[i]
}

答案1

你已经很接近了,只是让这项任务变得不必要地复杂化。尝试awk -f script.awk main.txt index.txt使用以下脚本(注意文件的相反顺序):

#!/bin/awk

BEGIN {
    FS = "|"
}
( NR == FNR ) {
    lookup[toupper($1)] = $0
}

( NR > FNR ) {
    key = toupper($1)
    n=split(lookup[key], replacements, "|")
    replacements[$2+1]=$3
    for (i=1; i<n+1; i++)
        printf "%s|", replacements[i]
    printf "\n"
}

结果是

 key1|1001|2000|3000|4000|
 key1|2001|2000|3000|4000|
 key2|1000|3001|3000|4000|
 key2|1000|4001|3000|4000|

不确定是否要将管道保留|在线路末端,但无论如何移除它们都是微不足道的。

您的方法的主要问题是,lookup每次新行key与前一行具有相同的值时,数组都会被覆盖。因此,必须颠倒文件的顺序 - 首先读取具有唯一第一个字段的文件,以将其用作数组索引。

顺便说一句,这是纯粹的解决方案,与任何其他 shellawk无关。ksh

相关内容