在处理 csv 数据时,我们会生成大量输出文件,每个文件包含 30,000 行。它们都具有相同的列/字段。它们也都是 csv 格式,我们将它们放在 Linux 服务器上的同一个文件夹中。这些文件使用日期、时间和数字的组合来唯一命名。见下文。
AB_20151127_120000_0_SEGMENT_FINAL.csv
AB_20151127_120000_1_SEGMENT_FINAL.csv
AB_20151127_120000_2_SEGMENT_FINAL.csv
AB_20151127_120000_3_SEGMENT_FINAL.csv
.
.
.
AB_20151127_120000_599_SEGMENT_FINAL.csv
所以现在我们需要将它们全部合并/加入到一个大文件中:(
AB_20151127_120000_SEGMENT_FINAL.csv
请注意合并文件中缺少的数字)
我尝试了awk
以下方法,但没有效果。请告诉我我做错了什么。
awk '"AB_20151127_120000_" NR-1 "_SEGMENT_FINAL.csv"' > AB_20151127_120000_SEGMENT_FINAL.csv
答案1
如果文件连接的顺序不重要,则使用:
cat AB_20151127_120000_*_SEGMENT_FINAL.csv > AB_20151127_120000_SEGMENT_FINAL.csv
如果顺序很重要,你就得发挥创造力。如果你知道段数,例如 599,你可以使用括号扩展 (只是\
为了方便阅读,这里只允许我将命令打印在两行上):
cat AB_20151127_120000_{0..599}_SEGMENT_FINAL.csv > \
AB_20151127_120000_SEGMENT_FINAL.csv
如果没有,你仍然可以使用括号扩展。只需选择一个足够大的数字,以确保所有文件都将被包含,并忽略有关不存在文件的错误消息:
cat AB_20151127_120000_{0..599}_SEGMENT_FINAL.csv > \
AB_20151127_120000_SEGMENT_FINAL.csv 2>/dev/null
或者,您可以生成已排序的文件名列表并使用它:
cat $(printf '%s\n' AB_20151127_120000_*_SEGMENT_FINAL.csv | sort -nt_ -k4) > \
AB_20151127_120000_SEGMENT_FINAL.csv
将printf
打印每个文件名,后跟传递给的换行符,sort
将-n
根据第 4 个字段 () 按数字方式对其进行排序 () ,其中字段由( )-t4
定义。_
-t_
答案2
如果您可以访问 Zsh shell,则该任务可以简化为单个命令:
cat AB_20151127_120000_*(n)_SEGMENT_FINAL.csv >AB_20151127_120000_SEGMENT_FINAL.csv
这是因为(n)
通配符限定符强制*
通配模式扩展为按自然顺序而不是字典顺序排序的文件名列表。
为了进行比较,Bash 中的文件名扩展:
$ for f in *; do echo "$f"; done
AB_20151127_120000_0_SEGMENT_FINAL.csv
AB_20151127_120000_10_SEGMENT_FINAL.csv
AB_20151127_120000_1_SEGMENT_FINAL.csv
AB_20151127_120000_2_SEGMENT_FINAL.csv
AB_20151127_120000_3_SEGMENT_FINAL.csv
在 Zsh 中使用(n)
通配符限定符进行文件名扩展:
% for f in *(n); do echo "$f"; done
AB_20151127_120000_0_SEGMENT_FINAL.csv
AB_20151127_120000_1_SEGMENT_FINAL.csv
AB_20151127_120000_2_SEGMENT_FINAL.csv
AB_20151127_120000_3_SEGMENT_FINAL.csv
AB_20151127_120000_10_SEGMENT_FINAL.csv