使用 AWK 合并文件,同时在前后添加分隔符
Merge files with AWK while adding separators before and after
我正在尝试使用 AWK 执行以下操作:
- 从文件夹中读取一系列文件。
- 将它们全部合并到一个文件中。
- 在这样做的同时,我想在每个文件的开头 和结尾 放置一个分隔符(实际上是一段代码,开始和结束标签,但在这个例子中为了清楚起见,我使用了一个简单的分隔符。
我希望在输出中看到的内容:
--Separator : Beginning of File--
((Content of file1.txt))
--Separator : End of File--
--Separator : Beginning of File--
((Content of file2.txt))
--Separator : End of File--
--Separator : Beginning of File--
((Content of file3.txt))
--Separator : End of File--
等...
我有这个代码片段,适用于 "Beginning of File" 分隔符:
INPUT="../folder/*.txt"
OUPUT="../output.txt"
awk 'FNR==1{print "--Separator : Beginning of File--"}{print}' $INPUT > $OUTPUT
现在我想弄清楚下一步:检测每个文件的结尾,并在那里放一个分隔符。
我找到了几个使用 END 进行单个文件操作的示例,但它们只检测最后一个文件的最后一行。
使用 GNU awk,简单
awk 'BEGINFILE { print "--Separator : Beginning of File--" } ENDFILE { print "--Separator : End of File--" } 1' file1 file2 file3
可读格式:
BEGINFILE { print "--Separator : Beginning of File--" }
ENDFILE { print "--Separator : End of File--" }
1
其中前两行似乎不言自明; BEGINFILE
和 ENDFILE
是特定于 GNU 的条件,分别适用于已处理文件的开头和结尾。最后一种是不加改变地打印行的惯用方式。 1
表示为真,因此此条件适用于所有行,并且在没有关联操作的情况下,将为它们执行默认操作 - 打印。
POSIX-一致:
awk 'BEGIN { start = "--Separator : Beginning of File--"; end = "--Separator : End of File--"; print start } FNR == 1 && FNR != NR { print end; print start } { print } END { print end }' file1 file2 file3
可读格式:
BEGIN {
# In the beginning, put the separators in variables so we don't have to
# repeat ourselves
start = "--Separator : Beginning of File--"
end = "--Separator : End of File--"
# and print the first beginning separator
print start
}
# For the first line of all files (FNR == 1) except that of the first
# file (in the first file, the file record number FNR is equal to the
# overall record number NR, so FNR != NR tests for this)
FNR == 1 && FNR != NR {
# print the end separator for the previous file
# and the start separator for this one.
print end
print start
}
# print all lines unchanged (no condition means it applies unconditionally)
{ print }
END {
# and in the end, print the last end separator.
print end
}
如果你不熟悉 awk,在 shell 中非常简单:
for file in ../folder/*.txt; do
echo "--start"
cat "$file"
echo "--end"
done > ../output.txt
我正在尝试使用 AWK 执行以下操作:
- 从文件夹中读取一系列文件。
- 将它们全部合并到一个文件中。
- 在这样做的同时,我想在每个文件的开头 和结尾 放置一个分隔符(实际上是一段代码,开始和结束标签,但在这个例子中为了清楚起见,我使用了一个简单的分隔符。
我希望在输出中看到的内容:
--Separator : Beginning of File--
((Content of file1.txt))
--Separator : End of File--
--Separator : Beginning of File--
((Content of file2.txt))
--Separator : End of File--
--Separator : Beginning of File--
((Content of file3.txt))
--Separator : End of File--
等...
我有这个代码片段,适用于 "Beginning of File" 分隔符:
INPUT="../folder/*.txt"
OUPUT="../output.txt"
awk 'FNR==1{print "--Separator : Beginning of File--"}{print}' $INPUT > $OUTPUT
现在我想弄清楚下一步:检测每个文件的结尾,并在那里放一个分隔符。
我找到了几个使用 END 进行单个文件操作的示例,但它们只检测最后一个文件的最后一行。
使用 GNU awk,简单
awk 'BEGINFILE { print "--Separator : Beginning of File--" } ENDFILE { print "--Separator : End of File--" } 1' file1 file2 file3
可读格式:
BEGINFILE { print "--Separator : Beginning of File--" }
ENDFILE { print "--Separator : End of File--" }
1
其中前两行似乎不言自明; BEGINFILE
和 ENDFILE
是特定于 GNU 的条件,分别适用于已处理文件的开头和结尾。最后一种是不加改变地打印行的惯用方式。 1
表示为真,因此此条件适用于所有行,并且在没有关联操作的情况下,将为它们执行默认操作 - 打印。
POSIX-一致:
awk 'BEGIN { start = "--Separator : Beginning of File--"; end = "--Separator : End of File--"; print start } FNR == 1 && FNR != NR { print end; print start } { print } END { print end }' file1 file2 file3
可读格式:
BEGIN {
# In the beginning, put the separators in variables so we don't have to
# repeat ourselves
start = "--Separator : Beginning of File--"
end = "--Separator : End of File--"
# and print the first beginning separator
print start
}
# For the first line of all files (FNR == 1) except that of the first
# file (in the first file, the file record number FNR is equal to the
# overall record number NR, so FNR != NR tests for this)
FNR == 1 && FNR != NR {
# print the end separator for the previous file
# and the start separator for this one.
print end
print start
}
# print all lines unchanged (no condition means it applies unconditionally)
{ print }
END {
# and in the end, print the last end separator.
print end
}
如果你不熟悉 awk,在 shell 中非常简单:
for file in ../folder/*.txt; do
echo "--start"
cat "$file"
echo "--end"
done > ../output.txt