将所有文件附加到 unix 中的一个文件,并使用第一个和最后一个文件名的一部分重命名输出文件

Append all files to one single file in unix and rename the output file with part of first and last filenames

例如,我有以下 2015 年 2 月 16 日至 20 日的日志文件。现在我想创建一个名为 mainentrywatcherReport_2015-02-16_2015-02-20.log 的文件。所以换句话说,我想从每周(周一至周五)的第一个和最后一个文件中提取日期格式,并在每个周六创建一个输出文件。我将在每个星期六使用 cron 来触发脚本。

$ ls -l
mainentrywatcher_2015-02-16.log  
mainentrywatcher_2015-02-17.log   
mainentrywatcher_2015-02-18.log    
mainentrywatcher_2015-02-19.log  
mainentrywatcher_2015-02-20.log  

$ cat *.log >> mainentrywatcherReport_2015-02-16_2015-02-20.log  
$ mv *.log archive/

任何人都可以帮助如何将输出文件重命名为上述格式?

像这样:

#!/bin/sh
LOGS="`echo mainentrywatcher_2[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].log`"
HEAD=
TAIL=
for logs in $LOGS
do
    TAIL=`echo $logs | sed -e 's/^.*mainentrywatcher_//' -e 's/\.log$//'`
    test -z "$HEAD" && HEAD=$TAIL
done
cat $LOGS >mainentrywatcherReport_${HEAD}_${TAIL}.log
mv $LOGS archive/

即:

  • 获取变量 $LOGS
  • 中现有日志的列表(恰好已排序)
  • 遍历列表,根据示例仅获取日期
  • 将第一个日期保存为 $HEAD
  • 将最后日期保存为 $TAIL
  • 循环后,将所有这些文件都放入新的输出文件中
  • 将用完的日志文件移动到存档目录中。

也许试试这个:

parta=`ls -l | head -n1 | cut -d'_' -f2 | cut -d'.' -f1`
partb=`ls -l | head -n5 | cut -d'_' -f2 | cut -d'.' -f1`
filename=mainentrywatcherReport_${parta}_${partb}.log
cat *.log >> ${filename}
  • "ls -l" 问题中描述了输出
  • "head -nX"取输出的第X行
  • "cut -d'_' -f2" 取下第一个下划线后的所有内容(剩下的)
  • "cut -d'.' -f1" 乘以第一个周期之前的所有(剩余)
  • 这两个命令都被 ` 标记包围(在波浪号 ~ 上方)以将命令的输出捕获到变量
  • 文件名将去除不必要的两个日期与最终文件名所需的其他格式组合在一起。
  • cat 命令演示了一种使用结果文件名的可能方法

编码愉快!如果您有任何问题,请发表评论。

如果你想引入简单的循环,你可以试试这个...

从=ls -lrt mainentrywatcher_* | awk '{print }' | head -1 | cut -d"_" -f2 | cut -d"." -f1

TO=ls -lrt mainentrywatcher_* | awk '{print }' | tail -1 | cut -d"_" -f2 | cut -d"." -f1

FINAL_LOG=mainentrywatcherReport_${FROM}_${TO}.log

我在ls -lrt mainentrywatcher_* | awk '{print }' 做 猫 $i >> $FINAL_LOG 完成

回声"All Logs Stored in $FINAL_LOG"

另一种方法给出你的日常文件和测试内容如下:

mainentrywatcher_2015-02-16.log  ->  a
mainentrywatcher_2015-02-17.log  ->  b
mainentrywatcher_2015-02-18.log  ->  c
mainentrywatcher_2015-02-19.log  ->  d
mainentrywatcher_2015-02-20.log  ->  e

利用bash参数expansion/substring提取将是一个简单的循环:

#!/bin/bash

declare -i cnt=0                                # simple counter to determine begin
for i in mainentrywatcher_2015-02-*; do         # loop through each matching file
    tmp=${i//*_/}                               # isolate date
    tmp=${tmp//.*/}
    [ $cnt -eq 0 ] && begin=$tmp || end=$tmp    # assign first to begin, last to end
    ((cnt++))                                   # increment counter
done

cmbfname="${i//_*/}_${begin}_${end}.log"        # form the combined logfile name

cat ${i//_*/}* > $cmbfname                      # cat all into combined name

## print out begin/end/cmbfname & contents to verify
printf "\nbegin: %s\nend  : %s\nfname: %s\n\n" $begin $end $cmbfname

printf "contents: %s\n\n" $cmbfname

cat $cmbfname

exit 0

use/output:

alchemy:~/scr/tmp/stack/tmp> bash weekly.sh

begin: 2015-02-16
end  : 2015-02-20
fname: mainentrywatcher_2015-02-16_2015-02-20.log

contents: mainentrywatcher_2015-02-16_2015-02-20.log

a
b
c
d
e

当然,您可以修改 for loop 以接受包含部分文件名的位置参数,并从命令行传递部分文件名。