我有很多文本文件,在一个文件夹中只有一个行浮点值,我想在bash中连接它们,例如:file_1.txt,file_2.txt ... file_N.txt。我想按照从1到N的顺序将它们放在一个txt文件中。有人可以帮帮我吗?这是我的代码,但它只是以随机方式连接它们。谢谢
for file in *.txt
do
cat ${file} >> output.txt
done
答案 0 :(得分:4)
尽管我建议不要解析ls
的输出,但我们继续。
ls
有"版本排序"将您想要的编号文件排序的选项。请参阅下面的演示。
要连接,您需要:
ls -v file*.txt | xargs cat > output
$ touch file{1..20}.txt
$ ls
file1.txt file12.txt file15.txt file18.txt file20.txt file5.txt file8.txt
file10.txt file13.txt file16.txt file19.txt file3.txt file6.txt file9.txt
file11.txt file14.txt file17.txt file2.txt file4.txt file7.txt
$ ls -1
file1.txt
file10.txt
file11.txt
file12.txt
file13.txt
file14.txt
file15.txt
file16.txt
file17.txt
file18.txt
file19.txt
file2.txt
file20.txt
file3.txt
file4.txt
file5.txt
file6.txt
file7.txt
file8.txt
file9.txt
$ ls -1v
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
file7.txt
file8.txt
file9.txt
file10.txt
file11.txt
file12.txt
file13.txt
file14.txt
file15.txt
file16.txt
file17.txt
file18.txt
file19.txt
file20.txt
答案 1 :(得分:2)
for file in *.txt
do
cat ${file} >> output.txt
done
这适用于我以及:
for file in *.txt
do
cat $file >> output.txt
done
您不需要{}
但更简单的仍然是:
cat file*.txt > output.txt
因此,如果您在评论中建议的文件超过9个,则可以执行以下操作之一:
files=$(ls file*txt | sort -t"_" -k2g)
files=$(find . -name "file*txt" | sort -t "_" -k2g)
files=$(printf "%s\n" file_*.txt | sort -k1.6n) # Thanks to glenn jackman
然后:
cat $files
或
cat $(find . -name "file*txt" | sort -t "_" -k2g)
最好仍然是正确编号文件,如果文件少于100个则为file_01.txt,如果小于1000则为file_001.txt,依此类推。
示例:
ls file*txt
file_1.txt file_2.txt file_3.txt file_4.txt file_5.txt file_10.txt
它们只包含相应的数字。
$ cat $files
1
2
3
4
5
10
答案 2 :(得分:1)
使用此:
find . -type f -name "file*.txt" | sort -V | xargs cat -- >final_file
如果文件已编号,那么排序不会以我们期望的自然方式进行。要实现这一点,您必须使用带有sort
命令的-V选项。
答案 3 :(得分:1)
正如其他人所指出的,如果您有文件file_1
,file_2
,file_3
... file_123283
,这些文件的内部BASH排序将file_11
在file_2
之前1}}因为它们按文字排序而不是数字排序。
您可以使用sort
获取所需的订单。假设您的文件是file_#
...
cat $(ls -1 file_* | sort -t_ -k2,2n)
ls -1
每行列出一个文件。sort -t_
表示用下划线打破排序字段。这使得第二个排序字段成为文件名的数字部分。-k2,2n
表示按数字排序第二个字段。然后,您将所有文件连接在一起。
一个问题是,如果您拥有大量文件,最终可能会填满命令行缓冲区。在cat
获取文件名之前,必须首先展开$(...)
。
答案 4 :(得分:1)
这对我有用......
for i in $(seq 0 $N); do [[ -f file_$i.txt ]] && cat file_$i.txt; done > newfile
或者,更简洁
for i in $(seq 0 $N); do cat file_$i.txt 2> /dev/null ;done > newfile
答案 5 :(得分:0)
您可以使用ls列出文件:
for file in `ls *.txt`
do·
cat ${file} >> output
done
这里讨论了一些排序技术:Unix's 'ls' sort by name
答案 6 :(得分:0)
两种解决方案适用于手边的特定案例,但 一般 打破带有嵌入空格或其他元字符的文件名(使用未加引号时的字符对shell具有特殊含义)。
以下解决方案适用于带有嵌入空格的文件名等。:
sort -z
和xargs -0
的系统的优先解决方案
(例如, Linux,OSX,* BSD ):printf "%s\0" file_*.txt | sort -z -t_ -k2,2n | xargs -0 cat > out.txt
使用NUL (空字符,0x0
)来分隔文件名,从而安全地保留其边界。
这是最强大的解决方案,因为它甚至可以正确处理带有换行符的文件名(尽管这种文件名在实践中非常罕见)。很遗憾,sort -z
和xargs -0
不符合 POSIX标准。
符合POSIX标准的解决方案,使用xargs -I
:
printf "%s\n" file_*.txt | sort -t_ -k2,2n | xargs -I % cat % > out.txt
处理基于行,并且由于使用-I
,每个输入文件名调用一次{em},这使得此方法变慢比上面那个。