使用AWK合并文件,同时在前后添加分隔符

使用AWK合并文件,同时在前后添加分隔符,awk,Awk,我正在尝试使用AWK执行以下操作: 从文件夹中读取一系列文件 将它们合并到一个文件中 在执行此操作时,我希望在每个文件的开头和结尾放置一个分隔符(实际上是一块代码、开始和结束标记,但为了清晰起见,在本例中我使用了一个简单的分隔符) 我希望在输出中看到的内容: --Separator : Beginning of File-- ((Content of file1.txt)) --Separator : End of File-- --Separator : Beginning of Fi

我正在尝试使用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--
等等

我有一段代码片段,用于“文件开头”分隔符:

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
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
}
其中前两行似乎不言自明
BEGINFILE
ENDFILE
是GNU特有的条件,分别应用于处理文件的开头和结尾。最后一种是一种惯用的打印行不变的方法
1意味着true,因此此条件适用于所有行,并且在没有相关操作的情况下,对它们执行默认操作(打印)

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
可读格式:

BEGINFILE { print "--Separator : Beginning of File--" }
ENDFILE   { print "--Separator : End of File--" }
1
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
}
使用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
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
}
其中前两行似乎不言自明
BEGINFILE
ENDFILE
是GNU特有的条件,分别应用于处理文件的开头和结尾。最后一种是一种惯用的打印行不变的方法
1意味着true,因此此条件适用于所有行,并且在没有相关操作的情况下,对它们执行默认操作(打印)

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
可读格式:

BEGINFILE { print "--Separator : Beginning of File--" }
ENDFILE   { print "--Separator : End of File--" }
1
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中非常简单:

用于../folder/*.txt中的文件;做
回音--“开始”
cat“$file”
回音--“结束”
完成>。/output.txt

如果您不受awk的束缚,它在shell中非常简单:

用于../folder/*.txt中的文件;做
回音--“开始”
cat“$file”
回音--“结束”
完成>。/output.txt

对。对于OP-non-gawk解决方案,如果您有任何空的输入文件,那么它的行为可能会不理想,因为它只会表现为它们不存在,而不是添加中间没有任何内容的开始/结束分隔符。这是个问题吗?太棒了!我在Mac OSX上运行awk,所以第二个版本对我有效。@Wintermute–我很想在您的代码示例中添加一些行返回,以便更清楚地说明它们的作用。在其当前形状中,线条太长,无法完整显示。我相信这些都是很好的例子,可以帮助初学者理解awk是如何工作的。是的,这主意不错。我在做的时候发表了一些评论。对于OP-non-gawk解决方案,如果您有任何空的输入文件,那么它的行为可能会不理想,因为它只会表现为它们不存在,而不是添加中间没有任何内容的开始/结束分隔符。这是个问题吗?太棒了!我在Mac OSX上运行awk,所以第二个版本对我有效。@Wintermute–我很想在您的代码示例中添加一些行返回,以便更清楚地说明它们的作用。在其当前形状中,线条太长,无法完整显示。我相信这些都是很好的例子,可以帮助初学者理解awk是如何工作的。是的,这主意不错。我在做这件事的时候发表了一些评论。谢谢,这确实是一个很好的工作选择。我将在这些文件中替换几个正则表达式,这就是为什么awk似乎是最合适的工具。同意。如果开始/结束分隔符相当“哑”,您可以在循环中将
cat
替换为
awk
,谢谢,这确实是一个很好的替代方案。我将在这些文件中替换几个正则表达式,这就是为什么awk似乎是最合适的工具。同意。如果开始/结束分隔符相当“哑”,则可以在for循环中将
cat
替换为
awk