【问题标题】:replace nth column value using a lookup text through awk通过 awk 使用查找文本替换第 n 列值
【发布时间】:2018-07-26 12:28:37
【问题描述】:

我已经搜索并帮助了我的方式,但现在我被卡住了。 基本上我有一个像这样的文本文件:

"02/01/2018 08:34:15"|"02/01/2018 08:34:16"|"Completed"|"70000000000006632150"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"**580**"|"1600"||"355672079017"||"1600"|"590279"|"588679"|7|101369|102577|-1|200158
"02/01/2018 08:34:03"|"02/01/2018 08:34:04"|"Completed"|"70000000000006632146"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"**601**"|"1100"||"355696369862"||"1106"|"591379"|"590279"|7|101369|102577|-1|200158
"02/01/2018 08:33:17"|"02/01/2018 08:33:18"|"Completed"|"70000000000006632123"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"**319**"|"1100"||"355694523968"||"1103"|"592479"|"591379"|7|101369|102577|-1|200158

我想用与代码匹配的名称替换粗体值。我已经创建了一个这样的查找文件

"319"|"AS003"
"601"|"Z 477"
"580"|"Z 478"
"101"|"AS006"

我正在使用 awk 搜索第一个文件,从第二个文件中找到相应的值,替换它并将所有内容写入一个新文件。 一切都适用于 319 和 101,但不适用于其他,我怀疑这是由于 Z 和代码之间的空间。 在我正在使用的代码下方:

tail -n +2 file_name | while read line  ####used tail _n +2 to exclude header
do
code=$(echo $line | awk -F'|' '{print $12}' FS=\|)
cn=$(awk -v CID=$code '$1==CID {print $2}' FS=\| lookup_file)
echo $line|awk -v CN=$cn 'BEGIN {FS=OFS="|"} {$12=CN} 1' >> test2.txt
done

对于查找文件中带有空格的行,我在终端中收到此错误:

awk: code_value"
awk:    ^ unterminated string 

它没有写入输出文件

欢迎提出任何建议...

【问题讨论】:

  • 一团糟-_-。祝你好运

标签: awk


【解决方案1】:

awk 可以做到这一切,前提是您的映射文件不是太大而无法读入内存。使用 awk 引用文件可能会很痛苦,但我认为这并不重要。

$ cat file.txt
"02/01/2018 08:34:15"|"02/01/2018 08:34:16"|"Completed"|"70000000000006632150"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"580"|"1600"||"355672079017"||"1600"|"590279"|"588679"|7|101369|102577|-1|200158
"02/01/2018 08:34:03"|"02/01/2018 08:34:04"|"Completed"|"70000000000006632146"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"601"|"1100"||"355696369862"||"1106"|"591379"|"590279"|7|101369|102577|-1|200158
"02/01/2018 08:33:17"|"02/01/2018 08:33:18"|"Completed"|"70000000000006632123"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"319"|"1100"||"355694523968"||"1103"|"592479"|"591379"|7|101369|102577|-1|200158


$ cat map.txt
"319"|"AS003"
"601"|"Z 477"
"580"|"Z 478"
"101"|"AS006"


$ awk 'BEGIN{FS=OFS="|"} FNR==NR{map[$1]=$2;next} {$12=map[$12]; print}' map.txt file.txt
"02/01/2018 08:34:15"|"02/01/2018 08:34:16"|"Completed"|"70000000000006632150"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"Z 478"|"1600"||"355672079017"||"1600"|"590279"|"588679"|7|101369|102577|-1|200158
"02/01/2018 08:34:03"|"02/01/2018 08:34:04"|"Completed"|"70000000000006632146"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"Z 477"|"1100"||"355696369862"||"1106"|"591379"|"590279"|7|101369|102577|-1|200158
"02/01/2018 08:33:17"|"02/01/2018 08:33:18"|"Completed"|"70000000000006632123"|"Activation"||"22200995102577"|"External System"|"ALFUNC ASBS"|"ASBS Shpk"|"VF Shop Asbs 1_209"|"AS003"|"1100"||"355694523968"||"1103"|"592479"|"591379"|7|101369|102577|-1|200158

awk 代码首先将 OFS 设置为 |因为我们正在更改字段,所以对于第一个文件,由读取的总行数等于当前文件行确定,我们构建第一个到第二个字段的映射,然后在第二个文件上我们从该映射中查找值。

编辑: 如 cmets 所述,如果未映射,我的代码将为空白 $12,使用

awk 'BEGIN{FS=OFS="|"} FNR==NR{map[$1]=$2;next} {$12=($12 in map ? map[$12] : $12); print}'  map.txt file.txt 

而是将值保留在原位。

【讨论】:

  • @EdMorton 感谢您指出这些事情。我到处都能看到你,所以感谢你的建议。
  • 嘿,谢谢您的回复,效果很好。只是一个小评论,最后的文件名应该被交换,所以数据文件第 1 和查找文件 2 以供任何人返回:)
  • 不,它们不应该是 - 我的回答显示的是您将在此处收到的确切文件、代码和输出。如果您想使用此代码将数据文件中的值替换为查找文件中的值,则需要先读取查找文件并创建映射,然后根据数据文件中的值检查该映射。请参阅FNR==NR 上的此答案以了解更多信息 - stackoverflow.com/questions/32481877/what-is-nr-fnr-in-awk
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2021-06-27
  • 2013-08-14
  • 2019-01-04
相关资源
最近更新 更多