【问题标题】:sed substitues with a single timestamp value for all the recordssed 用单个时间戳值替换所有记录
【发布时间】:2022-11-14 21:24:29
【问题描述】:

我正在尝试用当前时间戳替换字符串中的一个单词,为此我正在使用 sed。但是,sed 使用所有 1000 条记录的单个时间时间戳值更新字符串。如何更新记录以获得实际时间戳。

cat toreplacefile.txt
TIMESTAMP_line1 
TIMESTAMP_line2 
TIMESTAMP_line3 
TIMESTAMP_line4 
TIMESTAMP_line5

sed 's/TIMESTAMP/$(date +"%Y-%m-%dT%H:%M:%S.%3N")/g' toreplacefile.txt

2022-11-14T10:11:43.654_line1
2022-11-14T10:11:43.654_line2
2022-11-14T10:11:43.654_line3
2022-11-14T10:11:43.654_line4
2022-11-14T10:11:43.654_line5

However, what I am expecting is a time change atleast in milliseconds.
2022-11-14T10:11:43.654_line1
2022-11-14T10:11:43.656_line2
2022-11-14T10:11:43.657_line3
2022-11-14T10:11:43.660_line4
2022-11-14T10:11:43.661_line5

【问题讨论】:

  • 使用您发布的 sed 命令,您无法获得您声称的结果,因为单引号会禁止执行 date 命令。即使有正确的引用,我也不希望毫秒值改变,直到文件真的很大,因为行的处理很可能在同一毫秒内完成。也许使用旧的、非常慢的计算机会有所帮助。
  • @user1934428 有没有其他方法可以在不使用 sed 的情况下实现时间戳的更改。
  • 当然:编写一个 shell 循环,逐行读取文件,并为每一行生成一个您喜欢的输出时间戳。如果您在循环中放置sleep,则可以生成相隔几秒的时间戳。

标签: bash awk sed


【解决方案1】:

您需要自己减慢代码的执行速度才能看到时间戳的差异,例如使用“while 循环”逐行浏览文件:

while read -r line
do
    echo "$line" | sed "s/TIMESTAMP/$(date +"%Y-%m-%dT%H:%M:%S.%3N")/"
done < toreplacefile.txt

# result
2022-11-14T21:59:41.875_line1
2022-11-14T21:59:41.887_line2
2022-11-14T21:59:41.901_line3
2022-11-14T21:59:41.913_line4
2022-11-14T21:59:41.924_line5

编辑

不使用sed 的一种潜在选择:

while read -r line
do
     echo "${line//TIMESTAMP/$(date +"%Y-%m-%dT%H:%M:%S.%3N")}"
done < toreplacefile.txt

# result
2022-11-14T22:00:01.126_line1
2022-11-14T22:00:01.132_line2
2022-11-14T22:00:01.138_line3
2022-11-14T22:00:01.149_line4
2022-11-14T22:00:01.155_line5

【讨论】:

    【解决方案2】:

    GNU sed 有一个非常方便的扩展,允许使用 shell 执行替换的结果。并且由于为您输入的每一行都生成了一个新的 shell,这足够慢,可以看到时间差异。用你的例子:

    $ sed -E 'h;s/.*/date +%FT%T.%3N/e;G;s/(.*)
    (.*)TIMESTAMP//' ~/tmp/toreplacefile.txt 
    2022-11-14T13:03:04.995_line1
    2022-11-14T13:03:05.005_line2
    2022-11-14T13:03:05.016_line3
    2022-11-14T13:03:05.025_line4
    2022-11-14T13:03:05.033_line5
    

    也就是说,对于 &lt;PREFIX&gt;TIMESTAMP&lt;SUFFIX&gt; 行:

    • 将模式空间(当前行)存储在保持空间中。
    • date +%FT%T.%3N替换模式空间,用shell执行结果,用结果替换模式空间。
    • 添加一个新行,后跟保留空间的内容(原始行)。

    此时模式空间包含类似的内容(在日期和原始行之间有一个换行符):

    2022-11-14T13:03:04.995
    <PREFIX>TIMESTAMP<SUFFIX>
    
    • 最后一次使用替换命令得到&lt;PREFIX&gt;2022-11-14T13:03:04.995&lt;SUFFIX&gt; 没有换行符。

    注意:您可以尝试更简单的方法:

    sed 's/TIMESTAMP/date +%FT%T.%3N/e' 
    

    但这只是因为 date +%FT%T.%3N_line1 输出类似 2022-11-14T13:03:04.995_line1 的内容。对于更复杂的行前缀和/或后缀,它可能不会。您可能会遇到错误甚至更糟(想象一下 TIMESTAMP; rm -rf * 会发生什么)。所以,更喜欢安全版本。

    【讨论】:

      猜你喜欢
      • 2018-03-13
      • 2020-02-09
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多