我有 2 个包含列表的文件。第 1 列是用户 ID,第 2 列是关联值
# cat file1
e3001 75
n5244 30
w1453 500
#cat file2
d1128 30
w1453 515
n5244 30
e3001 55
要考虑的事情。
- userIds 可能不会在两个文件中完全排序
- userId 的数量可能因文件而异
必需的
- 首先,file1:column1 中的 userId 必须与 file2:column1 中的 UserId 匹配
- 接下来将它们在 file1:column2 中的值与 file2:column2 进行比较
- 打印值有差异的地方。如果有的话,还有额外的用户 ID
输出:
e3001 has differnece, file1 value: 75 & file2 value: 55
w1453 has differnece, file1 value: 500 & file2 value: 515
d1128 is only present in filename: file1|file2
欢迎使用 1liner-awk 或 bash 循环的解决方案
我正在尝试循环,但它在吐垃圾,猜想有一些错误的逻辑
#!/usr/bin/env bash
## VARIABLES
FILE1=file1
FILE2=file2
USERID1=(`awk -F'\t' '{ print $1 }' ${FILE1}`)
USERID2=(`awk -F'\t' '{ print $1 }' ${FILE2}`)
USERDON1=(`awk -F'\t' '{ print $2 }' ${FILE1}`)
USERDON2=(`awk -F'\t' '{ print $2 }' ${FILE2}`)
for user in ${USERID1[@]}
do
for (( i = 0; i < "${#USERID2[@]}"; i++ ))
#for user in ${USERID2[@]}
do
if [[ ${USERID1[$user]} == ${USERID2[i]} ]]
then
echo ${USERID1[$user]} MATCHES BALANCE FROM ${FILE1}: ${USERDON1[$i]} WITH BALANCE FROM ${FILE2}: ${USERDON2[$i]}
else
echo ${USERID1[$user]}
fi
done
done
下面是从 linux 框中复制的文件。它是制表符分隔的,但据我所知,awk 也可以与制表符一起使用。
#cat file1
e3001 55
n5244 30
w1453 515
嗯——可以这么说,你的剧本走的是风景优美的路线。一个简单的
awk
方法怎么样?喜欢它将 file1 的所有内容读入一个数组,然后,对于 file2 中的每一行,检查
$1
数组索引,如果存在,则打印差异(如果没有则不打印),并delete
s 数组元素(delete
可能是在某些 awk 实现中缺少,顺便说一句)。如果不存在,请相应打印。在该END
部分中,将打印所有剩余的数组元素,因为它们仅存在于 file1 中。对于这类事情,shell 是一个可怕的工具。此外,作为一般规则,您应该避免在您的 shell 脚本中为您的 shell 变量使用大写字母。由于按照惯例,全局环境 shell 变量是大写的,这可能导致命名冲突和难以调试的问题。最后,您的脚本需要分别读取文件 4 次(!),然后处理数据。
话虽如此,这是另一种 awk 方法(坦率地说,RudiC更好,但我已经写了这个,所以无论如何我都会发布):
评论不言自明:
基本上与 RudiC 发布的解决方案相同,但没有全部大写的变量名称,并且对清晰度进行了其他一些小的改进: