用分隔符合并文件
1. 概述
在本教程中,我们将了解如何通过在 Linux 中插入分隔符来合并文件。在某些情况下,我们需要简单地合并文件或在合并的文件之间添加分隔符。
假设我们有三个文件fruits.txt、vegetables.txt和meat.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 命令。