我在目录中有多个(超过100个)文本文件,如
files_1_100.txt
files_101_200.txt
文件的内容是一些变量的名称,如files_1_100.txt
包含一些介于1到100 之间的变量名称
"var.2"
"var.5"
"var.15"
类似地,files_201_300.txt
包含101到200 之间的一些变量
"var.203"
"var.227"
"var.285"
CCD_ 3作为
"var.1010"
"var.1006"
"var.1025"
我可以使用命令合并它们
cat files_*00.txt > ../all_files.txt
但是,文件的内容并不遵循父文件中的内容。例如all_files.txt
显示
"var.1010"
"var.1006"
"var.1025"
"var.1"
"var.5"
"var.15"
"var.203"
"var.227"
"var.285"
那么,我如何确保files_1_100.txt
的内容先出现,然后是files_201_300.txt
,再是files_1001_1100.txt
,使得all_files.txt
的内容是
"var.1"
"var.5"
"var.15"
"var.203"
"var.227"
"var.285"
"var.1010"
"var.1006"
"var.1025"
让我试试,但我认为这会奏效:
ls file*.txt | sort -n -t _ -k2 -k3 | xargs cat
这个想法是将文件列表进行排序,然后将它们传递给cat命令。
排序使用几个选项:
- -n-使用数字排序而不是字母排序
- -t-使用下划线字符将输入(文件名)划分为多个字段
- -k2-k3-先按第2个字段排序,然后按第3个字段排序(2个数字)
您已经说过,您的文件名为file_1_100.txt、file_101_201.txt等。如果这意味着(似乎表明)第一个数字"chunk"总是唯一的,那么您可以省略-k3
标志。只有当您最终使用file_100_2.txt和file_100_10.txt时,才需要该标志,因为您必须查看第二个数字"chunk"来确定首选顺序。
根据您正在处理的文件数量,您可能会发现指定glob(文件*.txt)可能会淹没shell,并导致行过长的错误。如果是这样的话,你可以这样做:
ls | grep '^file.*.txt$' | sort -n -t _ -k2 -k3 | xargs cat
您可以使用printf
sort
并将其管道传输到xargs cat
:
printf "%s " f*txt | sort -z -t_ -nk2 | xargs -0 cat > ../all_files.txt
请注意,整个管道都在处理以NULL结尾的文件名,因此确保该命令甚至适用于带有空格/换行符等的文件名。
如果文件名没有任何特殊字符或空格,那么其他答案应该是简单的解决方案。否则,请尝试这种基于rename
的方法:
$ ls files_*.txt
files_101_200.txt files_1_100.txt
$ rename 's/files_([0-9]*)_([0-9]*)/files_000$1_000$2/;s/files_0*([0-9]{3})_0*([0-9]{3})/files_$1_$2/' files_*.txt
$ ls files_*.txt
files_100_100.txt files_101_200.txt
$ cat files_*.txt > outputfile.txt
$ rename 's/files_0*([0-9]*)_0*([0-9]*)/files_$1_$2/' files_*.txt
cat file_*
的默认排序行为是按字母排序,而不是按数字排序。
按数字顺序列出它们,然后对每个进行cat操作,将输出附加到某个文件中。
ls -1| sort -n |xargs -i cat {} >> file.out
您可以尝试使用for循环并逐个添加文件(当数字不是零填充时,-v会对文件进行正确排序)
for i in $(ls -v files_*.txt)
do
cat $i >> ../all_files.txt
done
或更方便的单行:
for i in $(ls -v files_*.txt) ; do cat $i >> ../all_files.txt ; done
您也可以使用Awk通过拆分和排序ARGV
:来实现这一点
awk 'BEGIN {
for(i=1; i<=ARGC-1; i++) {
if(i > 1) {
j=i-1
split(ARGV[i], curr, "_")
split(ARGV[j], last, "_")
if (curr[2] < last[2]) {
tmp=ARGV[i]
ARGV[i]=ARGV[j]
ARGV[j]=tmp
}
}
}
}1' files_*00.txt