将文件每一行的后半部分替换为另一个文件中的相应部分

将文件每一行的后半部分替换为另一个文件中的相应部分

我有两个文件 A 和 B。两个文件中的每一行都被视为一个项目。每个项目的格式都是固定的,由键和描述组成,并用空格分隔。如下例所示。

UASCH-XCF02-SP062 /users/documents/ark

第一部分UASCH-XCF02-SP062是重点,最后一部分/users/documents/ark是说明。文件 A 和 B 分别有 1000 和 100000 个项目。同一文件中的每个键都是唯一的,但文件 A 中的项的键也出现在文件 B 中,但描述不同。如下一个简单的例子所示。

文件A

UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2

文件B

UASCH-XCF02-SP062 /users/documents/ark3
UASCH-XXF02-SP063 /users/documents/ark4
UASCH-XXF03-SP064 /users/documents/ark5

我想将文件B中相同key对应的描述替换为文件A中key对应的描述。示例中的结果如下所示。

文件B

UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5

如何实现这个目标?

答案1

这可以使用 AWK 来完成:

$ awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5

编辑:由于 Ed 的评论,简化了 AWK 表达式的后半部分。

要编辑文件 B,请将 AWK 输出重定向到临时文件,然后用它替换文件 B,如下所示:

awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt >B.txt.tmp
mv B.txt.tmp B.tmp 

怎么运行的。我们首先将第一个文件(A)的所有键值对保存到一个关联数组中,使用NR==FNR习惯用法来区分第一个文件和第二个文件。然后,当我们遍历第二个文件 (B) 时,我们将检查当前密钥是否存在于第一个文件中,如果存在,我们将当前值替换为第一个文件中找到的值。

答案2

bash...如果bash是您的 shell,那么您只需使用 shell 内置函数即可完成此操作,不需要外部实用程序/命令...但是,在某些情况下,它可能比专用文本处理工具慢一点,但是尽管如此,了解一下还是会有帮助的。

array像这样声明一个关联数组:

declare -A array

A然后使用空格 ie作为内部字段分隔符将文件读入其中,如下所示:

while IFS=' ' read -r k v
  do
  array[$k]="$v"
  done < A

然后读取文件B行,比较键,替换值并打印最终结果,如下所示:

while IFS=' ' read -r k v
  do
  if [[ "${!array[*]}" =~ "$k" ]]
  then
  printf '%s %s\n' "$k" "${array[$k]}"
  else
  printf '%s %s\n' "$k" "$v"
  fi
  done < B

这将输出:

UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5

注意: 作为bash 数组是一维的,上述方法将适用于您的用例(IE钥匙和价值) 和类似的,但不适用于具有多个值的键,当每个额外值需要解析为单独的标记时。

答案3

排序是固定的,并且 'uniq' 可以只考虑前 N 个字符,所以......

cat AB | 排序 | uniq -w 17 > /tmp/foo ; cp /tmp/foo B

是的 - 它按预期工作

$ cat A B | sort | uniq -w 17
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5

相关内容