英文:
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
和nullglob
bash选项。 - 以可移植的方式列出它们(不建议在脚本中使用
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
extglob
andnullglob
bash options. - List them in a portable way (
ls
is 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论