我想将具有相同列和数据类型的 3 个(比如说)文件的数据合并到一个文件中,我可以进一步使用该文件进行处理。
目前我必须一个接一个地处理这些文件。因此,我正在寻找一种可以在脚本中编写的解决方案,将所有文件合并到一个文件中。
例如:
文件1:
mike,sweden,2015
tom,USA,1522
raj,india,455
文件 2:
a,xyz,155
b,pqr,3215
c,lmn,3252
预期合并文件3:
mike,sweden,2015
tom,USA,1522
raj,india,455
a,xyz,155
b,pqr,3215
c,lmn,3252
请帮我解决这个问题。
最佳答案
回答问题的原始形式:
正如@Lars 在对该问题的评论中所述,看起来需要输入文件的简单串联,这正是cat
的用途(甚至>命名为):
cat file1 file2 > file3
为了满足您稍后添加的要求:
#!/bin/sh
# Concatenate the input files and sort them with duplicates removed
# and save to output file.
cat "$1" "$2" | sort -u > "$3"
但请注意,您可以将串联和排序合并为一个步骤,如 Jean-Baptiste Yunès's answer 所示。 :
# Sort the input files directly with duplicates removed and save to output file.
sort -u "$1" "$2" > "$3"
请注意,使用排序
是消除重复项的最简单方法。
如果您不想排序,则必须使用不同的、更复杂的方法,例如与awk
:
#!/bin/sh
# Process the combined input and only
# output the first occurrence in a set of duplicates to the output file.
awk '!seen[$0]++' "$1" "$2" > "$3"
!seen[$0]++
是一种常见的 awk
习惯用法,仅打印一组重复项中的第一个:
seen
是一个关联数组,其中填充每个输入行 ($0
) 作为键(索引),每个元素根据需要创建。这意味着一组重复项中的所有行(即使不相邻)都引用相同数组元素。
在数字上下文中,
awk
的变量值和数组元素隐式为0
,因此当给定的输入行出现时 第一次并应用后递减 (++
),元素的结果值为1
。- 只要以后遇到该行的重复项,数组元素的值就会递增。
最终效果是,对于任何给定的输入行,如果在 中看到输入行,
!seen[$0]++
返回 true第一次,并且每个重复项(如果有)假。请注意,++
由于是后增量,因此仅在之后!seen[$0]
后应用已评估。!
否定seen[$0]
的值,导致值为0
- 即 < em>false 在 bool 上下文中返回 true,任何非零值(遇到重复项)返回 false。
!seen[$0]++
是awk
中所谓的模式的实例 - 评估条件确定是否应处理关联的操作(代码块)的输入行。这里,没有任何操作,在这种情况下,awk
隐式简单地打印输入行,如果!seen[$0]++
指示>正确。总体效果是:按输入顺序打印行,但对于有重复的行,仅打印第一个实例,有效消除重复。
请注意,对于重复项很少的大型输入文件,此方法可能会出现问题,因为大多数数据必须保存在内存中。
关于shell - 在 unix shell 脚本中将多个文件合并为单个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35665861/