合并多个文本文件

有时需要合并多个文本文件。

首先我们看一下有这四个文件,

➜  ls                               
week2.md week3.md week4.md week5.md

我们要把它合成一个文件。通过搜索、学习,我知道了有许多命令可以做这个事。

使用 cat 的操作步骤

基本使用如下:

➜  cat week2.md week3.md week4.md week5.md > Sep-cat.md

还可以使用 Unix 的 glob pattern 简化一下:

➜  cat week{2..5}.md > Sep-cat.md

这里的{2..5} 就是 2 到 5。

此时,如果结果中有多余的空行,可以加上 -s 去掉:

➜  cat -s week{2..5}.md > Sep-cat.md

此时,如果发现有多个文件的内容合并在一行上,是由于前面文件的末尾没有换行符,可以使用简单的循环搞定:

for file in week{2..5}.md; do {cat -s "$file"; echo} done > Sep-cat-echo.md

这里 echo 后面默认会有换行符。

注意:这里 done 不能有 ;,否则表示语句结束,会直接输出到屏幕。

使用 paste 的操作步骤

此外,还有 paste 命令可以部分的完成这个功能:

paste -s -d '\n' week{2..5}.md > Sep-paste.md

paste 本身没有压缩空行的选项,所以还得借助于 cat:

paste -s -d '\n' week{2..5}.md | cat -s - > Sep-paste.md

但,这还是有点Bug,因为没法处理”多个文件的内容合并在一行上“这个问题。我还没想到怎么弄,有知道的同学请不吝赐教。

命令参考

Cat

看一下它的说明,

cat – concatenate and print files

连接并打印文件。

语法

cat [-belnstuv] [file …]

描述

The cat utility reads files sequentially, writing them to the standard output. The file operands are processed in command-
line order. If file is a single dash (‘-’) or absent, cat reads from the standard input.

依次读取一个或多个文件,然后将它们写到标准输出。file 这个操作符是按照命令行的顺序去处理的。如果这个 file 是一个单独的横线 - 或者没有的话,就是从标准输入——比如键盘——读取的。

接下来就是一些选项,我们现在用到的就是 -s

-s Squeeze multiple adjacent empty lines, causing the output to be single spaced.

把多行相邻的空行给它转换成一行。

echo

DESCRIPTION
The echo utility writes any specified operands, separated by single
blank (‘ ’) characters and followed by a newline (‘\n’) character, to
the standard output.

echo 后面默认跟一个换行符 \n

paste

NAME
paste – merge corresponding or subsequent lines of files

合并多个文件对应的行或者是随后的行。

对应行就是按行号来对应,file1的第1行和file2的第1行合并,file1的第2行和file2的第2行合并,以此类推。

DESCRIPTION
The paste utility concatenates the corresponding lines of the given
input files, replacing all but the last file’s newline characters with
a single tab character, and writes the resulting lines to standard
output.

多个文件按行合并——最后一个文件它的换行符还需要保留,其它的文件里面的换行符全部给它替换为 tab ,然后再合并,这样的话所有的文件的对应行都在最后输出结果的那个对应行。

-s Concatenate all of the lines of each separate input file
in command line order. The newline character of every
line except the last line in each input file is replaced
with the tab character, unless otherwise specified by the
-d option.

把每一个独立的输入文件按命令行上的顺序连接起来,刚才我们是按行连接的,我们第一个文件的第一行和第二个文件的第一行连起来,现在我们是把第一个文件的所有行取出来连接到第二个文件,第二个文件连第三个文件,而且还是按照你的命令行的顺序来。

但是它这里是把每一个文件除了最后一个文件里面的所有的换行符都替换为 tab。 那这样的话所有的文件内容都相当于被压缩在一起了,因为它们的原来的换行都没有了。

除非指定了 -d 选项。

-d list Use one or more of the provided characters to replace the
newline characters instead of the default tab.

原来是用换行 tab 去替换原来的换行符,现在你可以指定你要用什么去替换。

之前,我们为了按文件合并,使用了 -s 但是它有一个副作用就是把换行符给整没了,因此我们再用 -d '\n' 给它加回来。

本作品采用《CC 协议》,转载必须注明作者和本文链接
日拱一卒
讨论数量: 10
bouc

可以先用 echo 追加一个空行到文件末尾, 再用 cat -s 压缩文件的多余的空行

echo >> $file; cat -s $file
2个月前 评论
hustnzj (楼主) 2个月前
bouc (作者) 2个月前
hustnzj (楼主) 2个月前

对于:

如果发现有多个文件的内容合并在一行上,是由于前面文件的末尾没有换行符

好像这个命令也能搞定?

sed '$s/.$/&\n/' week{2..5}.md
2个月前 评论
wxf666 (作者) 1个月前
hustnzj (楼主) 1个月前
wxf666 (作者) 1个月前
hustnzj (楼主) 1个月前
wxf666 (作者) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
93
粉丝
83
喜欢
150
收藏
121
排名:67
访问:11.4 万
私信
所有博文
社区赞助商