【问题标题】:comparing files and replacing data in shell script [duplicate]比较文件并替换 shell 脚本中的数据 [重复]
【发布时间】:2020-02-05 17:35:23
【问题描述】:

我想将 file.txt 的第 1 列与 test.txt 的第 2 列相匹配,以将 test.txt 的第 2 列替换为 files.txt 中相应的第 1,2 和 3 列。有人可以建议使用 bash 脚本的最佳方法吗?

以下是 2 个文件: test.txt

pcs_err 102 0 1580917083
too_long 103 0 1580917083
emc_out 103 0 1580917083
too_long 104 0 1580917083
emc_out 104 0 158091708
link_failt 104 0 1580917083
loss_sig 104 0 1580917083

文件.txt

102 1 10 0efd40 N16 Online F-Port 52:4a 
103 1 11 0e5e00 N16 Online F-Port 20:01
104 2 0 0e2200 N16 Online F-Port 20:01
105 2 1 0e5700 N16 Online F-Port 20:01

所需的输出如下所示,

pcs_err.1.10.102 0 1580917083
too_long.1 11.103 0 1580917083
emc_out.1.11.103 0 1580917083
too_long.2.0.104 0 1580917083
emc_out.2.0.104 0 158091708
link_failt.2.0.104 0 1580917083
loss_sig.2.0.104 0 1580917083

【问题讨论】:

  • 请发布您想要实现的输出。将join-o 一起使用。
  • 欢迎来到 SO。因此,我们确实鼓励用户添加他们为解决自己的问题而付出的努力,因此请在您的问题中添加相同的内容。此外,您的示例预期输出也不清楚您想要获得它。

标签: bash shell awk sed data-manipulation


【解决方案1】:

所以这里有一个快速的单行...

awk 'NR==FNR{a[$1]=$2"."$3"."$1;next} {$1=$1"."a[$2];$2=""} 1' file.txt test.txt

或者为了更容易阅读(和评论)......

NR==FNR {             #  For the first file specified...
  a[$1]=$2"."$3"."$1  #  store an array with the first field as a key.
  next
}
{                     #  For the second+ file specified...
  $1=$1"."a[$2]       #  append contents of the array to the first field,
  $2=""               #  empty the now-redundant second field,
}
1                     #  and print.

这有一点间距问题,因为当我们清空$2 时,我们会在其周围留下分隔符。如果这是一个问题,您可以通过用稍微复杂的printf 替换此部分和您的打印命令来解决这个问题:

NR==FNR {
  a[$1]=$2"."$3"."$1
  next
}
{
  printf "%s.%s %s %s%s", $1, a[$2], $3, $4, ORS
}

这样做的好处是您可以更精细地控制输出格式。风险在于,如果您的输入格式发生变化,您的代码的弹性可能会降低。 YMMV。

【讨论】:

  • 谢谢,这就像一个魅力。我想知道是否可以在 awk 中使用 if 语句从 a[2] 中的 a[1] 中删除不存在的条目,而不是仅仅将其留空。如果这不可能,我打算使用 sed/awk 和 if 语句来清理这只是好奇。
  • @sri .. 绝对可以使用if。如果其中一个是 awk,您几乎从不需要通过多个文本处理工具进行管道传输。请注意,您还可以在依赖于数组的命令语句中使用条件,例如$2 in a {。您可以man awk 了解有关语法的更多详细信息。下次,请记住在您的问题的示例输入中包含此类示例及其处理的解释(以及您自己解决此问题的尝试)。
  • 谢谢。通过在脚本的下一步中使用另一个 awk 语句,我得到了预期的结果,下面是我使用的,这也帮助我摆脱了 awk 语句中打印的额外空间。 awk '$1 ~/[0-9]$/ { print $1,$2,$3 }' new.txt
猜你喜欢
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多