Contents

用分隔符合并文件

1. 概述

在本教程中,我们将了解如何通过在 Linux 中插入分隔符来合并文件。在某些情况下,我们需要简单地合并文件或在合并的文件之间添加分隔符。

假设我们有三个文件fruits.txtvegetables.txtmeat.txt

$ cat fruits.txt 
Apple
Orange
Grapes
$ cat vegetables.txt 
Cabbage
Lettuce
Broccoli
$ cat meat.txt 
Pork
Beef
Mutton

我们将研究如何做到这一点的不同方式。

2. 使用循环

我们可以使用 for 循环编写一个简单的 Bash 单行代码来连接这些文件。在循环内部,我们对每个文件进行cat ,然后将输出重定向到一个单独的文件。

让我们看看如何实现:

$ for f in *.txt; do cat $f >> out.txt; done;
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

使用该命令,我们可以看到文件的内容已合并到 out.txt文件中。

使用 for循环很灵活。我们可以做额外的处理,比如在文件之间添加一个新行或插入一个不同的分隔符。为此,我们只需要在 do和 done关键字之间添加命令:

$ for f in *.txt; do cat $f >> out.txt; echo >> out.txt; done;
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

在这里,**我们使用 echo命令在文件之间插入一个新行,**正如我们所见,它工作得非常好。

3.使用 find命令

这类似于上面的循环解决方案。我们可以使用find 命令来模拟循环,而不是使用for循环。

让我们看看实际效果:

$ find *.txt -exec cat {} \; > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

我们可以看到它将所有文件的内容连接到 out.txt。find 命令查找所有 txt文件并使用*-exec*选项,我们可以对它们进行 cat以生成 out.txt文件。

我们可以添加更多*-exec*选项以在文件之间插入换行符

$ find *.txt -exec cat {} \; -exec echo \; > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

同样,我们也可以使用 xargs 命令和find命令来连接文件

$ find *.txt | xargs -I{} sh -c "cat {}; echo" > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

4. 使用 sed命令

我们使用 sed 命令修改文本输入流。让我们看看如何使用 sed命令来合并文件:

$ sed '' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

正如我们在上面看到的,我们使用了sed命令的默认操作来合并文件。

让我们看看如何使用sed命令在每个文件后插入一个换行符。正如我们所知,sed命令有一些选项可以使用*$*符号来标识文本输入的结尾和一行的结尾 。

让我们看一个例子:

$ echo "test end of line" | sed '$s/$/\n/'
test end of line
$

在这里,我们可以看到在文本输入后插入了一个新行。让我们分解 sed命令部分:

  • $s – 选择范围作为最后一行
  • $ ——第二个符号代表行尾
  • \n - 是行尾的替代品

因此,它获取文件的最后一行,找到该行的结尾,并用新行替换它。

让我们使用它在文件之间插入一个新行:

$ sed -e '$s/$/\n/' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$ 

从上面的结果中,我们可以看到输出包含一个新行,但仅在文件末尾。我们需要在每个文件后换行。

要解决这个问题,在表达式选项 (-e) 之后, 我们可以使用 sed命令的 -s选项。这将使 sed单独处理文件,并且我们在每个文件的末尾换行

让我们来看看它:

$ sed -e '$s/$/\n/' -s *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

现在,我们可以看到输出在每个文件末尾后都有一个新行。此外,如果我们需要在文件之间使用不同的分隔符,我们可以在 sed模式中的换行符之后添加该分隔符字符串。

5. 使用 awk命令

awk 是一个强大的命令行实用程序,用于处理文本。我们将使用 AWK 语言中的print和 $0关键字来连接文件:

让我们看一个合并文件的简单示例:

$ awk '{print $0}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

如上所示,print命令显示值,而 $0 代表正在处理的记录。

因此,该命令打印给定文件中的每条记录以连接它们。

让我们看看如何在每个文件后插入分隔符。为此,我们可以使用 END关键字。它将识别记录中的最后一行。

让我们修改命令以包含以下内容:

$ awk '{print $0} END{printf "\n"}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

如我们所见,它打印了换行符,但仅在最后一行。它没有在每个文件之后打印新行。

为了解决这个问题,我们可以使用 AWK语言中的 FILENAME标识符。它保存当前正在处理的文件的名称。使用此标识符,我们可以检查文件是否已更改,然后插入新行:

$ awk '{ if (FILENAME != file){ if (file) printf "\n"; file = FILENAME } } {print $0} END{printf "\n"}' *.txt > out.txt
$ cat out.txt 
Apple
Orange
Grapes
Pork
Beef
Mutton
Cabbage
Lettuce
Broccoli
$

虽然这有点麻烦,但从结果中,我们可以看到每个文件后都插入了一个换行符。当然,用它来连接文件是很愚蠢的。但是我们已经通过这个练习学到了一两个 awk 命令。