0

我有两个属性文件,我想用文件 B 中的任何匹配键/值条目替换文件 A 中的键/值对。文件 A 的条目将比文件 B 多 - 预计这两个文件不会具有完全相同的条目数。此外,文件 B 可能包含文件 A 中未包含的条目。

举个例子:

File A
"GB" = "United Kingdom";
"SE" = "Sweden";
"BR" = "Brazil";
"FR" = "France";
"ES" = "Spain";
"DE" = "Germany";

File B
"GB" = "Regno Unito";
"SE" = "Svezia";
"BR" = "Brasile";
"BR" = "Brasile";
"CL" = "Cile";

Desired Result
"GB" = "Regno Unito";
"SE" = "Svezia";
"BR" = "Brasile";
"FR" = "France";
"ES" = "Spain";
"DE" = "Germany";
"CL" = "Cile";

是否可以使用 bash 执行此搜索和替换?

谢谢,

肖恩

4

2 回答 2

2

这是一种使用方法GNU awk

awk -F " = " 'FNR==NR { array[$1]=$2; next } $1 in array { sub ($2, array[$1]) }1' fileb filea

结果:

"GB" = "Regno Unito";
"SE" = "Svezia";
"BR" = "Brasile";
"FR" = "France";
"ES" = "Spain";
"DE" = "Germany";

编辑:

您可以在发生替换后简单地删除数组元素。然后在脚本的最后,打印出剩下的内容:

awk -F " = " 'FNR==NR { array[$1]=$2; next } $1 in array { sub ($2, array[$1]); delete array[$1] }1; END { for (i in array) print i FS array[i] }' fileb filea

结果:

"GB" = "Regno Unito";
"SE" = "Svezia";
"BR" = "Brasile";
"FR" = "France";
"ES" = "Spain";
"DE" = "Germany";
"CL" = "Cile";
于 2012-11-01T00:34:51.173 回答
1

以下仅 bash 脚本将输出您要求的结果:

#!/bin/bash

# Identify our files. If you want, test for their existence before proceeding.
fileA="$1"
fileB="$2"

# Define an associated array
declare -A countries

# Read our initial data
while read cc junk name; do
 if [[ -n "$cc" ]]; then
   countries["$cc"]="$name"
 fi
done < "$fileA"

# Overwrite array elements with updated values
while read cc junk name; do
 if [[ -n "$cc" ]]; then
   countries["$cc"]="$name"
 fi
done < "$fileB"

# Print the results
for cc in "${!countries[@]}"; do
  echo "$cc = ${countries[$cc]}"
done

结果的顺序不会完全相同,但我怀疑这并不重要。如果是,您可以创建一个额外的数组,其索引是一个计数器,然后代替 final for cc in ...,您可以简单地遍历该数组以获取$countries正确顺序的索引。让我知道这是否重要而您无法弄清楚。

我只在此处发布此内容,因为您要求提供 bash 解决方案。Steve 的awk脚本要简洁得多,而且可能要快得多。(只是猜测。可能甚至不值得花时间对其进行基准测试。)

于 2012-11-01T03:39:26.367 回答