属性文件搜索和替换

时间:2012-11-01 00:22:35

标签: bash shell unix scripting

我有两个属性文件,我想用文件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替换?

谢谢,

肖恩

2 个答案:

答案 0 :(得分: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";

答案 1 :(得分: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

结果不会完全相同,但我怀疑这并不重要。如果是,您可以创建一个其索引为计数器的附加数组,然后您可以简单地遍历该数组以正确的顺序获取for cc in ...索引,而不是最终的$countries。如果这很重要,请告诉我,你无法弄明白。

我只在这里发帖,因为你要求一个bash解决方案。史蒂夫的awk脚本更简洁,可能更快。 (只是猜测。可能甚至不值得花时间进行基准测试。)