如何在 bash 中提取文件名的不同字段?

如何在 bash 中提取文件名的不同字段?

我有一些日志文件要融合。文件名的格式environment.type-YYYY-MM-DD.log如下:

  • environment代表服务器的环境:“private”、“public”、“para”等)
  • type是“主要”、“次要”、“错误”等。
  • YYYY-MM-DD代表文件创建日期。

所有文件类型均可在所有服务器中找到:“主要”、“次要”和“错误”文件可在私有、公共和准服务器中找到;例如private.error-2021-09-10.log,,,,。public.error-2021-09-11.log​​public.primary-2021-09-08.logpublic.error-2021-15.log

由于相同类型的文件可以在不同的服务器中找到,因此我必须分别融合公共、私有和para服务器的主文件,并对错误和辅助文件执行相同的操作。文件必须在某个日期范围内同样融合(一个月中每 7 天融合一次文件)。

我的方法是使用以下条件:

  1. 将服务器名称(公共、私有和para)与文件名称中的名称进行比较,以便根据相应的服务器对文件进行分组。
  2. 将文件类型(错误、主要和次要)与文件名中的文件类型进行比较,以便仅融合每个服务器中相应类型的文件。
  3. 比较日期范围(一个月内最多 7 天才能获得融合文件)。

为此,我需要一些命令来提取服务器名称、文件类型和日期,以便与我将包含在条件中的值进行比较,并按照上面的方法中所述单独融合文件。

我尝试使用:*.log | awk -F'[_.]' '{print $1}'提取环境(字段 1)部分,并尝试*.log | awk -F'[_.]' '{print $2}'提取文件类型(字段 2),但它不起作用。

答案1

使用您的示例文件名集:

private.error-2021-09-10.log
public.error-2021-09-11.log
public.primary-2021-09-08.log
public.error-2021-15.log

我假设最后一个文件名中缺少的“-MM-”部分是一个拼写错误......

这是一个使用 awk 的示例,可能适合您:

获取“环境”:

ls *.log | awk -F'[.-]' '{print $1}'

结果:

private
public
public
public

获取“类型”:

ls *.log | awk -F'[.-]' '{print $2}'

结果:

error
error
error
primary

获取日期戳:

ls *.log | awk -F'[.-]' '{print $3 "-" $4 "-" $5}'

结果:

2021-09-10
2021-09-11
2021-15-log
2021-09-08

编辑: 从下面的评论中,我想添加不解析输出的选项,ls因为这很容易出现其他问题。

你可以试试这个:

for file in *.log; do
  echo "$file" | awk -F'[.-]' '{print $1}'
  echo "$file" | awk -F'[.-]' '{print $2}'
  echo "$file" | awk -F'[.-]' '{print $3 "-" $4 "-" $5}'
done

或者使用 find( find -type f -name "*.log" -exec awk -f'[.-]' '{print $1}' {} +;) 的东西,但也有一些需要注意的问题。

答案2

假设您的日志文件都与文件名通配模式匹配*.*-*.log,您可以循环它们的名称并将不同部分提取到单独的变量中。

for name in *.*-*.log; do
        tmpname=$name

        environment=${tmpname%%.*}; tmpname=${tmpname#*.}
        type=${tmpname%%-*};        tmpname=${tmpname#*-}
        date=${tmpname%.log}

        printf '"%s" --> %s + %s + %s\n' \
                "$name" "$type" "$environment" "$date"
done

此代码将名称的不同部分提取到三个变量environmenttype和中date。我们使用连续的步骤从 中名称的副本中提取并删除每个部分tmpname。我们正在使用标准参数替换,这比使用awk几次要快。

运行此示例:

$ ls
list                                public.error-2021-15.log
private.error-2021-09-10.log        public.primary-2021-09-08.log
public.error-2021-09-11.log         script
$ ./script
"private.error-2021-09-10.log" --> error + private + 2021-09-10
"public.error-2021-09-11.log" --> error + public + 2021-09-11
"public.error-2021-15.log" --> error + public + 2021-15
"public.primary-2021-09-08.log" --> primary + public + 2021-09-08

相关内容