bash - 使用该行的一部分索引到 file2 并查找值后,如何将值附加到 file1 中的每一行?

标签 bash sed grep comm

我基本上有以下两个文件:

$ cat file1.txt
AB,12 34 56,2.4,256,,
CD,23 45 67,10.8,257,,
EF,34 56 78,0.6,258,,
GH,45 67 89,58.3,259,,
...
$ cat file2.txt
AB,12 34 56,2.4,36
XY,56 99 11,3.6,15
ZQ,12 36 89,5.9,0
EF,34 56 78,0.6,99
GH,45 67 89,58.3,79
...

对于 file1.txt 中的每一行,我想使用前 3 个字段作为 file2.txt 中的索引,获取相应的最后一个字段,并将其放入 file1.txt 中,如下所示:

cat newfile.txt
AB,12 34 56,2.4,256,36,
CD,23 45 67,10.8,257,,
EF,34 56 78,0.6,258,99,
GH,45 67 89,58.3,259,79,

无法保证 file1 中的每一行都会出现在 file2 中,反之亦然,对于这种情况,newfile.txt 中上面显示的空字段就可以了。

在我的第一次尝试中,我在 while read 循环中读取 file1 中的每一行,然后在 file2 中查找相应的行,它可以工作,但速度太慢了。 file1 和 file2 各有数十万行。

有什么方法可以使用 sed 使用 file1 中每行的前 3 个字段作为 file2 的索引,查找我需要的值,并将其附加到 file1 中的该行吗?并且不逐行读取 file1 就这样做吗?

感谢任何帮助。

最佳答案

使用 joinsed (用于某些预处理和后处理),并假设 | 字符没有出现在两个文件中

join -a1 -t'|' \
    <(sort file1.txt | sed 's/,/|/3') \
    <(sort file2.txt | sed 's/,/|/3') |
    sed 's/,|//; s/|/,/; s/[^,]$/&,/' > newfile.txt

(使用问题中给出的输入进行测试)

它可以使用关联数组在普通的 bash 中完成,但我怀疑它是否有效。例如:

#!/bin/bash

declare -A tail

while IFS= read -r line; do
    if [[ $line =~ ([^,]*,){3} ]]; then
        tail[${BASH_REMATCH[0]}]=${line#"${BASH_REMATCH[0]}"}
    fi
done < file2.txt

while IFS= read -r line; do
    if [[ $line =~ ([^,]*,){3} ]] && [[ -n ${tail[${BASH_REMATCH[0]}]} ]]; then
        printf '%s%s\n' "${line%?}" "${tail[${BASH_REMATCH[0]}]},"
    else
        printf '%s\n' "$line"
    fi
done < file1.txt > newfile.txt

关于bash - 使用该行的一部分索引到 file2 并查找值后,如何将值附加到 file1 中的每一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66144862/

相关文章:

python - 如何使用 "at"unix 命令直接从终端调度 python 脚本?

c - 为什么我在 netstat/ifconfig 中看不到服务器正在运行?

linux - 使用带有正则表达式的 sed 来匹配不同的行

bash - ls | grep -v 在脚本中

linux - Grep 并插入一个字符串

linux - 如何使用 grep 或 awk 处理特定列(使用文本文件中的关键字)

python - 从非 root 用户执行 root 所需的脚本

sed 失败并出现 "unknown option to ` s'"错误

linux - 这个 RegExp 有什么问题?

linux - 为什么 uniq -c 命令在某些情况下会返回重复项?