英文:
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个主要的困难:
- 仅列出您想要的文件,不多不少:使用
extglob和nullglobbash选项。 - 以可移植的方式列出它们(不建议在脚本中使用
ls):使用正常的路径名扩展。 - 按照扩展名的逆数值顺序排序:使用
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:
- List only the files you want, no more: use the 
extglobandnullglobbash options. - List them in a portable way (
lsis not recommended for scripting): use regular pathname expansion. - 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 > 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*` >total_messages
or I might suggest using timestamps...
cat `ls -t messages*` >total_messages
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论