簡體   English   中英

macOS 上的 sed 搜索/替換:將引用傳遞回替換字符串中的另一個命令

[英]sed search/replace on macOS: Pass back reference to another command within the replace string

我在 macOS 上有一個包含一堆日志及其時間戳的文件。 時間戳的格式為“自紀元以來的秒數”,但我想將它們全部替換為“MM-DD-YY HH:MM:SS”格式。 例如:

自 Epoch 以來的1605726368.416115秒應替換為11-18-20 20:06:08 請注意,自 Epoch 時間戳是十進制值以來的秒數,這就是日志的時間戳記。

我試圖用seddate實現這一點,如下所示:

sed -E -i '' -e "s/^([0-9]+)([0-9.]+)/$(date -r \\1 '+%m-%d-%Y %X')/" logfile.txt

問題是date\\1解釋為僅 1 秒,而不是引用正則表達式中的([0-9]+)捕獲組的反向引用。 我嘗試了很多事情,比如用$1\\\\1替換\\1 ,搞亂單引號和雙引號,從自制軟件安裝 gnu-sed 並嘗試使用/e標志,但沒有任何效果。 所以我的問題基本上是否可以在 $(...) 命令替換中使用 \\N 反向引用(特別是在 sed 替換字符串的上下文中)?

如果可能,我想避免在 while 循環中讀取每一行並在每一行上調用sed ,因為這太慢了。

您不能對sed捕獲的值的反向引用進行命令替換,因為命令替換將在之前運行並且它將采用文字\\1而不是實際捕獲的值。

如果您對perl解決方案沒問題,那么這將正常工作:

perl -pe 's/^[0-9]+\.[0-9]+/{
use POSIX qw( strftime ); strftime("%m-%d-%Y %X", localtime($&));
}/e' file.log

PS:如果您的 EPOCH 值在GMT您可以使用gmtime而不是localtime

我將從兩個帶有paste糟糕解決方案開始,這可能會讓你感到開心。

當所有行都以時間戳開頭時,您可以使用

paste -d " " <(printf '%(%m-%d-%Y %X)T\n' $(cut -d"." -f1 logfile.txt)) \
             <(cut -d" " -f2- logfile.txt)

對於只有線戳的行,這將失敗,在接下來的幾年中,您可以使用

paste -d " " <(printf '%(%m-%d-%Y %X)T\n' $(cut -d"." -f1 logfile.txt)) <(cut -c19- logfile.txt)

您幾乎可以像以前一樣使用sed 首先提取命令,然后獲取它們。

. <(sed -E 's/^([0-9]+)([0-9.]+)(.*)/printf "%(%m-%d-%Y %X)T" "\1"; echo "\3"/' logfile.txt)

我認為awk是最好的:

awk -F "." '{ print strftime("%m-%d-%Y %X",$1) substr($0,17) }' logfile.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM