将多个文件归为一个文件,文件名在数据之前

Cat several files into one file with the file name before the data

我有几个包含数据的日志文件。我想要做的是将所有这些文件整合到一个文件中。但在数据进入之前,我希望文件名不带扩展名。例如: 我拥有的文件:

file1.log file2.log file3.log

我要的文件:all.log

all.log 里面有:

file1
    file1's data
file2
    file2's data
file3
    file3's data

使用 awk

awk 'FNR==1{sub(/[.][^.]*$/, "", FILENAME); print FILENAME} 1' file*.log >all.log

FNR为文件记录号。它位于每个文件的开头。因此,测试 FNR==1 告诉我们是否在文件的开头。如果是,那么我们使用 sub(/[.][^.]*$/, "", FILENAME) 从文件名中删除扩展名,然后打印它。

程序中的最后一个 1 是 awk 的神秘方式,即打印此行。

重定向 >all.log 将所有输出保存在文件 all.log 中。

使用shell

for f in file*.log; do echo "${f%.*}"; cat "$f"; done >all.log

或者:

for f in file*.log
do 
    echo "${f%.*}"
    cat "$f"
done >all.log

在 shell 中,for f in file*.log; do 开始循环匹配 glob file*.log 的所有文件。语句 echo "${f%.*}" 打印文件名减去扩展名。 ${f%.*} 后缀删除 的示例。 cat "$f" 打印文件的内容。 done >all.log 终止循环并将所有输出保存在 all.log.

即使文件名包含空格、制表符、换行符或其他难以理解的字符,此循环也能正常工作。

假设您有两个文件:

foo:

a
b
c

栏:

d
e
f

使用 Perl:

perl -lpe 'print $ARGV if $. == 1; close(ARGV) if eof' foo bar > all.log

foo
a
b
c
bar
d
e
f

$.是行号
$ARGV为当前文件名
close(ARGV) if eof 重置每个文件末尾的行号

使用 grep:

grep '' foo bar > all.log

foo:a
foo:b
foo:c
bar:d
bar:e
bar:f
for i in `ls file*`; do `echo $i | awk -F"." '{print }' >> all.log; cat $i >> all.log`; done