在bash中连接文本文件

时间:2014-07-24 12:50:44

标签: bash

我有很多文本文件,在一个文件夹中只有一个行浮点值,我想在bash中连接它们,例如:file_1.txt,file_2.txt ... file_N.txt。我想按照从1到N的顺序将它们放在一个txt文件中。有人可以帮帮我吗?这是我的代码,但它只是以随机方式连接它们。谢谢

for file in *.txt
do 
  cat ${file} >>  output.txt  
done 

7 个答案:

答案 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_1file_2file_3 ... file_123283,这些文件的内部BASH排序将file_11file_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 -zxargs -0系统的

优先解决方案(例如, Linux,OSX,* BSD ):

printf "%s\0" file_*.txt | sort -z -t_ -k2,2n  | xargs -0 cat > out.txt

使用NUL (空字符,0x0)来分隔文件名,从而安全地保留其边界。

这是最强大的解决方案,因为它甚至可以正确处理带有换行符的文件名(尽管这种文件名在实践中非常罕见)。很遗憾,sort -zxargs -0 不符合 POSIX标准。


符合POSIX标准的解决方案,使用xargs -I

printf "%s\n" file_*.txt | sort -t_ -k2,2n  | xargs -I % cat % > out.txt

处理基于,并且由于使用-I,每个输入文件名调用一次{em},这使得此方法变慢比上面那个。