将多个日志文件连接成一个单一文件,以自动化调试包生成。

huangapple go评论60阅读模式
英文:

Concatenate multiple log files into one single file to automate debug package generation

问题

以下是我文件夹中的文件:

messages        
messages.1      
messages.2      
messages.3      
messages.4      
messages.5      
messages.6      
messages.7

我想将这些文件合并成一个单一的文件(例如 log.txt),使其呈现如下:

messages.7 -> messages.6 -> messages.5 -> messages.4 -> messages.3 -> messages.2 -> messages.1 -> messages

我之前是手动执行 cat 命令,即:

cat messages.7 >> log.txt
cat messages.6 >> log.txt
cat messages.5 >> log.txt
cat messages.4 >> log.txt
cat messages.3 >> log.txt
cat messages.2 >> log.txt
cat messages.1 >> log.txt
cat messages >> log.txt

我想编写一个可以处理任意数量文件的 Bash 脚本。

FYI:messages 是包含最新日志的文件,而 messages.7 是最旧的文件。

另外,我不想颠倒文件内容。文件数量是动态的,并遵循相同的编号模式。

英文:

Here are the files in my folder:

messages        
messages.1      
messages.2      
messages.3      
messages.4      
messages.5      
messages.6      
messages.7

I want to merge this files in one single file(e.g. log.txt) so that it is in this way:

messages.7 -> messages.6 -> messages.5 -> messages.4 -> messages.3 -> messages.2 -> messages.1 -> messages

I was manually executing cat commands i.e.

cat messages.7 >> log.txt
cat messages.6 >> log.txt
cat messages.5 >> log.txt
cat messages.4 >> log.txt
cat messages.3 >> log.txt
cat messages.2 >> log.txt
cat messages.1 >> log.txt
cat messages >> log.txt

I want to write a bash script which can handle any number of files.

FYI: messages is file with latest logs and messages.7 is the oldest.

Also, I do not want to reverse the content of the file. Number of files are dynamic and follows the same numbering patterns.

答案1

得分: 2

有3个主要的困难:

  1. 仅列出您想要的文件,不多不少:使用extglobnullglob bash选项。
  2. 以可移植的方式列出它们(不建议在脚本中使用ls):使用正常的路径名扩展。
  3. 按照扩展名的逆数值顺序排序:使用sort

您可以尝试:

#!/usr/bin/env bash

shopt -s extglob nullglob
m=( messages?(.+([0-9])) )
printf '%s\n' "${m[@]}" | sort -t. -rnk2 | xargs cat >> log.txt

使用bash的extglob选项,messages?(.+([0-9]))会扩展为messages(如果文件存在),以及所有现有的messages.n文件,其中n是一个或多个数字的字符串。我们将文件名存储在数组m中,打印其内容并使用sort-t.(使用.作为字段分隔符)以及-rnk2(逆序,数值,第二个字段)选项进行管道传输。

nullglob bash选项会处理没有文件存在的情况(如果没有nullglob,路径名扩展会生成messages?(.+([0-9]))模式本身,这会导致错误,因为没有这样的文件存在)。

英文:

There are 3 main difficulties:

  1. List only the files you want, no more: use the extglob and nullglob bash options.
  2. List them in a portable way (ls is not recommended for scripting): use regular pathname expansion.
  3. Sort them in reverse numeric order of extension: use sort.

You can try:

#!/usr/bin/env bash

shopt -s extglob nullglob
m=( messages?(.+([0-9])) )
printf '%s\n' "${m[@]}" | sort -t. -rnk2 | xargs cat >> log.txt

With the extglob option of bash messages?(.+([0-9])) expands as messages (if the file exists) and all existing messages.n files where n is a string of one or more digits. We store the file names in array m, print its content and pipe to sort with the -t. (use . as field separator) and -rnk2 (reverse, numeric, second field) options.

The nullglob bash option takes care of the case where none of the files exist (without nullglob the pathname expansion produces the messages?(.+([0-9])) pattern itself, which causes an error because no such file exists).

答案2

得分: 1

关于答案的关键点是使用经过适当制作的 sort 命令来排序文件名。对于给定的文件名模式 messages[.N],命令将如下:

sort -t . -k 2 -n -r

-t . -k 2 允许按数值后缀排序,-n 实际上指示 sort 将 2 < 10,-r 反转输出的顺序。

因此,您可以使用以下方式来检查文件的顺序:

ls -1 messages* | sort -t . -k 2 -n -r

... 要实际获取连接的输出到 'total_messages':

ls -1 messages* | sort -t . -k 2 -n -r | xargs cat > total_messages
英文:

The key point of the answer is to use a properly crafted sort command for file names. For the given filename pattern messages[.N] the command would be:

sort -t . -k 2 -n -r

-t . -k 2 allows to sort by the numeric suffix, -n actually instructs sort to make 2 < 10, -r reverses the order of the output.

So you can use something like this to check the order of files:

ls -1 messages* | sort -t . -k 2 -n -r

... and to actually get the concatenated output in 'total_messages':

ls -1 messages* | sort -t . -k 2 -n -r | xargs cat &gt; total_messages 

答案3

得分: 1

"Strange that 7 is the oldest, but anyway...." 不寻常的是7是最老的,但无论如何...

"cat ls -r messages* >total_messages" 请注意,这部分是一条Linux命令,无需翻译。

"or I might suggest using timestamps..." 或者我可能建议使用时间戳...

"cat ls -t messages* >total_messages" 请注意,这部分也是一条Linux命令,无需翻译。

英文:

Strange that 7 is the oldest, but anyway....

cat `ls -r messages*` &gt;total_messages

or I might suggest using timestamps...

cat `ls -t messages*` &gt;total_messages

huangapple
  • 本文由 发表于 2023年6月6日 07:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定