使用 awk 将一条记录的字段复制到第二个文件中另一条记录的字段中

问题描述 投票:0回答:1

GNU Awk 5.1.0。 zsh,Ubuntu 22.04 我有一个包含一行记录的源文件(FS =“|”)source_file.txt

19-03-2024
Name            | formula           | no.  | dose | days | cost  | msg | em | notes | consult | WYLQ
John Doe        | XJZT+ML+SD        | 9979 | 4¾   | 14   | xx.xx | x   | 2  | xx    | ph      |
Jane Doe        | XJZT-BS+CS+MDP+FL | 9980 | 5    | 10   | xx.xx | x   | 1  | xx    | ph      | 

我想将 source_file.txt 中所选记录的字段 2,3,4,5 放置在 table.txt 记录 3 的字段 1,2,3,4 中。

我在终端中使用的命令链如下:

awk -v FS='|' -v OFS='|' '  $1 ~ /John Doe/ { print $2,$3,$4,$5 }' ~/source_file.txt > /tmp/record_grab.tmp | awk '{a[FNR]=$0}' /tmp/record_grab.tmp | awk -v FS='|' -v OFS='|'  'FNR==NR{a[FNR]=$0; next} {print $1,$2,$3,$4 a[FNR], $3}' /tmp/record_grab.tmp /home/table.txt

结果是:

| formula               | no. | dose      XJZT+ML+SD          | 9979 | 4¾    | 14    | no. 
| --------------------- | --- | -------- | --- 
|                       |     |   

预期结果是:

| formula               | no.  | dose     | days    |
| --------------------- | ---  | -------- | ------- |
| XJZT+ML+SD            | 9979 | 4¾       | 14      |

将 source_file.txt 中所选记录的字段 2,3,4,5 放置在 table.txt 记录 3 的字段 1,2,3,4 中

文件 record_grab.tmp 结果如预期:

cat /tmp/record_grab
XJZT+ML+SD        | 9997 | 4¾    | 7 

我意识到肯定有一种更优雅的方法来做到这一点,除了我在使用数组时犯了一个错误之外,它看起来像是将临时文件中的整行放入 table.txt 的字段 3 而不是记录 3 中我不知道如何纠正它。如有任何帮助,我们将不胜感激。

awk
1个回答
0
投票

我将利用 GNU

AWK
来完成此任务,让
file.txt
内容为

19-03-2024
Name            | formula           | no.  | dose | days | cost  | msg | em | notes | consult | WYLQ
John Doe        | XJZT+ML+SD        | 9979 | 4¾   | 14   | xx.xx | x   | 2  | xx    | ph      |
Jane Doe        | XJZT-BS+CS+MDP+FL | 9980 | 5    | 10   | xx.xx | x   | 1  | xx    | ph      | 

然后

awk 'BEGIN{FS=OFS="|"}NR==2{print "|" $2,$3,$4,$5 "|";for(i=2;i<=5;i+=1){$i=sprintf("%*s",length($i),"");gsub(/ /,"-",$i)};print "|" $2,$3,$4,$5 "|"}NR>2&&$1~/John Doe/{print "|" $2,$3,$4,$5 "|"}' file.txt

提供输出

| formula           | no.  | dose | days |
|-------------------|------|------|------|
| XJZT+ML+SD        | 9979 | 4¾   | 14   |

说明:我通知 GNU

AWK
,管道既是字段分隔符 (
FS
) 又是输出字段分隔符 (
OFS
),对于第二行,我打印包含在
|
中的所需列。然后,对于每个选定的列,我使用动态
sprintf
来获取由与给定列中的字符一样多的空格组成的字符串,然后使用破折号全局替换该字符串。我以某种方式将其作为标题行。对于第二行之后的每一行,并且在第一个字段内有
print
,我
John Doe
所需的列包含在
print
中。

(在 GNU Awk 5.1.0 中测试)

© www.soinside.com 2019 - 2024. All rights reserved.