我有 100,000 个 .txt 文件,格式如下:
bygrp,colnum,beta
100005,1,0.629519434191718
100005,2,-0.500000000026516
100005,3,0.560850895321124
100005,4,0.119624318119292
100005,5,0.257676682753309
文件名为 Job19_beta1.txt,...,job19_beta100000.txt
我创建了仅包含标题行的 total.txt:bygrp、colnum、beta。
我只想将 100,000 个文件中的第 3 行(表中的 colnum=2)附加到 total.txt 中,不带标题。
我该如何编写脚本来实现这一点?我想我需要编写 for...do...循环然后复制,但想不通……
我其实是一名 SAS 分析师,但有一个项目需要使用命令提示符上传数据。我在 Google 上搜索了很多代码,但仍然对脚本感到困惑。提前谢谢!
答案1
在 Linux 上的 Bash 上进行测试(不能保证 Windows 也是如此),这看起来很有希望:
for i in (*.txt)
do
tail -n +2 "$i" >> total.txt
done
for输出第二行及以后的内容,仅跳过第一行-n +2
。tail
或者从 a.txt 中的文件列表中读取(可能是多余使用 cat,并且文件名中没有换行符):
for i in $(cat a.txt)
do
tail -n +2 "$i" >> total.txt
done
或者使用find
也应该可以工作,如果 100,000 个文本文件都在同一个文件夹树中并且您需要进行一些挖掘,则可能会更容易。
find folder/ -name "*.txt" -exec tail -n +2 '{}' >> total.txt \;
答案2
要从文件读取文件名:
while IFS= read -r filename; do
sed 1d "$filename"
done < a.txt >> total.txt
更高效,因为您不必为每个文件调用 sed:
xargs awk 'FNR != 1' < a.txt >> total.txt
这将积累尽可能多的 awk 文件参数,只要命令可以容纳。
答案3
我想将 100,000 个文件中的所有数据附加到 total.txt 但不包含标题,因为它已经存在于 total.txt 中
在这种情况下,使用 bash 和 unix 风格的工具:
tail -qn +2 job19_beta{1..100000}.txt >>total.txt
怎么运行的
job19_beta{1..100000}.txt
扩展到您想要的文件列表按照正确的顺序。tail -qn +2 job19_beta{1..100000}.txt
这会将从第 2 行开始的所有文件的内容写入标准输出。
-n +2
告诉tail
从第 2 行开始。-q
告诉tail
保持安静并且在更改文件时不要打印标题。>>total.txt
这会导致 tail 命令的输出被附加到
total.txt
。
替代使用a.txt
如果您想从中读取文件名a.txt
,那么:
while IFS= read -r fname; do tail -n +2 "$fname"; done <a.txt >>total.txt
您没有提到文件名是如何分隔的,a.txt
因此我假设每行一个文件名。(请注意,文件名中可能包含换行符,因此这不是通用解决方案。)