从 shell 脚本中的文件行中提取指定日期

从 shell 脚本中的文件行中提取指定日期

我有文件 `StandardDefaults.txt,其内容如下

 [MetaInfo]
 fileName="BUStandardDefaultsFile.dat"
 schemaVersion="2"
 schemaLocation="sftp:/var/app/napsgl/cgdata/GLFSUTN1/intfc/dsmtout/ISG/Schema/BUStandardDefaultsFileSchema_02.json"
 generationTime="2023-06-13T10:19:13.060606"
 process_time"2023-06-14T08:29:13.060606"
 recordsCount=1041

我需要提取与generationTime值相关的日期预期输出:

 2023-06-13

我尝试使用从文件中grep获取。generationTime但我需要帮助来提取日期值。我想将日期值存储在字符串中。然后它将用于进一步处理。

答案1

awk

awk -F'["T]' '/^generationTime/ {print $3}' StandardDefaults.txt
2023-06-13

这告诉awk使用"T作为字段分隔符,然后在以以下内容开头的任何输入行上打印第三个字段generationTime

为什么是第三个字段?因为有大写TgenerationTime所以之前的所有内容都是 1 美元);第二个字段 $2 是从那里到第一个"字符的所有内容;第三个字段 $3 是从那里到下一个的所有内容T

generation   T  ime=   "  2023-06-13   T  10:19:13.060606   "
    $1      FS   $2   FS      $3      FS        $4         FS   $5 

FS 代表字段分隔符。 $5 将为空,因为最后一个字段分隔符之后没有任何内容"(但 awk 仍会将其算作该行上的第五个字段,因此 awk 的字段计数器变量NF将等于 5...这在这里并不重要,但可以是对于NF以某种方式使用的脚本很重要)。

要将 awk (或任何打印到 stdout 的程序)的输出存储在变量中,请使用命令替换,例如:

$ myvar=$(awk -F'["T]' '/^generationTime/ {print $3}' StandardDefaults.txt)

$ echo $myvar
2023-06-13

答案2

使用sed你可以提取你想要的部分,如下所示:

sed -n 's/.*generationTime="\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)T.*/\1/p' StandardDefaults.txt

或者,较短的变体是使用grep -PoPerl 兼容的正则表达式

grep -Po '(?<=generationTime=")[^T]*' StandardDefaults.txt

答案3

如果不是缺少=process_time它的值,那看起来很像 php 识别的 INI 文件类型parse_ini_file(),你可以这样做:

php -r '
  $ini = parse_ini_file($argv[1], true);
  echo $ini["MetaInfo"]["generationTime"] . PHP_EOL;
  ' -- your-file.ini

要将其放入 shell 变量中:

time=$(
  php -r '
    $ini = parse_ini_file($argv[1], true);
    echo $ini["MetaInfo"]["generationTime"];
  ' -- your-file.ini
)

照常。然后,您可以使用T...以下命令删除该部分${time%%T*}或在 php 中将其剥离:

date=$(
  php -r '
    $ini = parse_ini_file($argv[1], true);
    echo stristr($ini["MetaInfo"]["generationTime"], "T", true);
  ' -- your-file.ini
)

这也将是有效的TOML,因此您可以使用(附带的tomlq前端):jqyq

time=$(tomlq -r '.MetaInfo.generationTime' your-file.ini)
date=$(tomlq -r '.MetaInfo.generationTime|sub("T.*"; "")' your-file.toml)

大多数编程语言都有解析 TOML 的模块。从 3.11 开始,python3默认发货:

date=$(python3 -c '
import tomllib
import sys
c = tomllib.load(sys.stdin.buffer)
print(c["MetaInfo"]["generationTime"].partition("T")[0])
' < your-file.toml
)

虽然默认情况下通常不安装,但有一些是针对 perl 的。例如,与TOML::Tiny

date=$(
  perl -0777 -MTOML::Tiny -ne '
    print from_toml($_)->{MetaInfo}->{generationTime} =~ s/T.*//r
  ' your-file.toml
)

请注意,这些时间戳没有时区指示的事实表明它们可能采用 UTC,这意味着相应的日期部分可能与当地时间不同。

例如,在我写这篇文章时,它是2023-06-16T06:45:10UTC,但那是2023-06-15T23:45:10在美国洛杉矶。

要获取$local_dateUTC 时间戳的对应信息(例如2023-06-13T10:19:13.060606存储在 中)$timezsh例如:

zmodload zsh/datetime
TZ=UTC0 strftime -rs epoch '%Y-%m-%dT%H:%M:%S' ${time%.*} &&
  strftime -s local_date %Y-%m-%d $epoch

对于我在Europe/London时区来说,2023-06-13T10:19:13.060606这给出了2023-06-13,但对于Pacific/Midway例如某人来说,这给出了2023-06-12

jq(因此tomlq)还可以进行日期解析和格式化(尽管根据手册页,这还不稳定),因此可能是:

local_date=$(
   tomlq -r '.MetaInfo.generationTime |
               sub("\\.\\d+$"; "") |
               strptime("%Y-%m-%dT%H:%M:%S") |
               mktime |
               strflocaltime("%Y-%m-%d")' your-file.toml
)

相关内容