【问题标题】:How can I use sed line by line?如何逐行使用 sed?
【发布时间】:2020-09-27 11:50:47
【问题描述】:

我知道我做错了什么,但我不知道是什么。

#!/bin/bash

while IFS='' read -r line
    do
        new=$(git log -1 --pretty="format:%ct" $line)
        sed "s|$line: .*|: $new|" file.yml
    done < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml)

file.yml 内容:

catalog/view/css/animate.css/3.1.1/animate.min.css: 1484139539
catalog/view/fonts/cinzel/fonts.css: 1484139539
catalog/view/fonts/garamondcondot-book/fonts.css: 1484139539
catalog/view/fonts/gotham-narrow/fonts.css: 1484139539
catalog/view/fonts/gotham/fonts.css: 1484139539
catalog/view/fonts/greatvibes/fonts.css: 1484139539
catalog/view/fonts/indie-flower/fonts.css: 1484139539
catalog/view/fonts/katibeh/fonts.css: 1484139539
catalog/view/fonts/lobster-two/fonts.css: 1484139539

那么,我想做什么?

我有 file.yml 一些文件源和 UNIX 时间戳(最后修改日期)。我想用git log 检查每个文件。从git log 我收到新的时间戳修改日期,我需要用新日期替换旧日期。

我的预期:

catalog/view/css/animate.css/3.1.1/animate.min.css: 1484135987
catalog/view/fonts/cinzel/fonts.css: 1484136578

我得到了什么(以及为什么我认为 sed 不能逐行工作):

: 1549375252
catalog/view/javascript/auroraoverlay/overlay.css: 1484139539
catalog/view/javascript/customselect/css/styles.css: 1484139539
catalog/view/javascript/jquery/christmasTime/christmasTime.css: 1484139539
catalog/view/css/animate.css/3.1.1/animate.min.css: 1484139539
catalog/view/fonts/cinzel/fonts.css: 1484139539
catalog/view/fonts/garamondcondot-book/fonts.css: 1484139539
catalog/view/fonts/gotham-narrow/fonts.css: 1484139539
catalog/view/fonts/gotham/fonts.css: 1484139539
catalog/view/fonts/greatvibes/fonts.css: 1484139539
catalog/view/fonts/indie-flower/fonts.css: 1484139539
catalog/view/fonts/katibeh/fonts.css: 1484139539
catalog/view/fonts/lobster-two/fonts.css: 1484139539
catalog/view/fonts/museo/fonts.css: 1484139539
catalog/view/fonts/myriad-pro/fonts.css: 1484139539
catalog/view/fonts/notera/fonts.css: 1484139539
catalog/view/fonts/sr-cart-icons/fonts.css: 1484139539
catalog/view/javascript/auroraoverlay/ageprotector.css: 1484139539
: 1484139539
catalog/view/javascript/customselect/css/styles.css: 1484139539
catalog/view/javascript/jquery/christmasTime/christmasTime.css: 1484139539

catalog/view/css/animate.css/3.1.1/animate.min.css: 1484139539
catalog/view/fonts/cinzel/fonts.css: 1484139539
catalog/view/fonts/garamondcondot-book/fonts.css: 1484139539
catalog/view/fonts/gotham-narrow/fonts.css: 1484139539
catalog/view/fonts/gotham/fonts.css: 1484139539
catalog/view/fonts/greatvibes/fonts.css: 1484139539
catalog/view/fonts/indie-flower/fonts.css: 1484139539
catalog/view/fonts/katibeh/fonts.css: 1484139539
catalog/view/fonts/lobster-two/fonts.css: 1484139539
catalog/view/fonts/museo/fonts.css: 1484139539
catalog/view/fonts/myriad-pro/fonts.css: 1484139539
catalog/view/fonts/notera/fonts.css: 1484139539
catalog/view/fonts/sr-cart-icons/fonts.css: 1484139539
catalog/view/javascript/auroraoverlay/ageprotector.css: 1484139539
catalog/view/javascript/auroraoverlay/overlay.css: 1484139539
: 1484139539

catalog/view/javascript/jquery/christmasTime/christmasTime.css: 1484139539
catalog/view/css/animate.css/3.1.1/animate.min.css: 1484139539
catalog/view/fonts/cinzel/fonts.css: 1484139539
catalog/view/fonts/garamondcondot-book/fonts.css: 1484139539
catalog/view/fonts/gotham-narrow/fonts.css: 1484139539
catalog/view/fonts/gotham/fonts.css: 1484139539
catalog/view/fonts/greatvibes/fonts.css: 1484139539
catalog/view/fonts/indie-flower/fonts.css: 1484139539
catalog/view/fonts/katibeh/fonts.css: 1484139539
catalog/view/fonts/lobster-two/fonts.css: 1484139539
catalog/view/fonts/museo/fonts.css: 1484139539
catalog/view/fonts/myriad-pro/fonts.css: 1484139539
catalog/view/fonts/notera/fonts.css: 1484139539
catalog/view/fonts/sr-cart-icons/fonts.css: 1484139539
catalog/view/javascript/auroraoverlay/ageprotector.css: 1484139539
catalog/view/javascript/auroraoverlay/overlay.css: 1484139539
catalog/view/javascript/customselect/css/styles.css: 1484139539
: 1484139539

catalog/view/css/animate.css/3.1.1/animate.min.css: 1590479145
catalog/view/fonts/cinzel/fonts.css: 1590479145
catalog/view/fonts/garamondcondot-book/fonts.css: 1590479145
catalog/view/fonts/gotham-narrow/fonts.css: 1590479145
catalog/view/fonts/gotham/fonts.css: 1590479145
catalog/view/fonts/greatvibes/fonts.css: 1590479145
catalog/view/fonts/indie-flower/fonts.css: 1590479145
catalog/view/fonts/katibeh/fonts.css: 1590479145
catalog/view/fonts/lobster-two/fonts.css: 1590479145
catalog/view/fonts/museo/fonts.css: 1590479145
catalog/view/fonts/myriad-pro/fonts.css: 1590479145
catalog/view/fonts/notera/fonts.css: 1590479145
catalog/view/fonts/sr-cart-icons/fonts.css: 1590479145
catalog/view/javascript/auroraoverlay/ageprotector.css: 1590479145
catalog/view/javascript/auroraoverlay/overlay.css: 1590479145
catalog/view/javascript/customselect/css/styles.css: 1590479145
catalog/view/javascript/jquery/christmasTime/christmasTime.css: 1590479145

【问题讨论】:

  • "s|$line: .*|: $new|" 您正在输出文件内容并替换整行。
  • 好的,有什么建议吗?
  • 几个建议:1)将示例减少到几个文件(在那个巨大的输出块中的东西太多了),2)考虑构建一个新的时间戳文件,完成后覆盖原始文件(或将原始文件归档并将新文件重命名为file.yml);至于从file.yml ... awk -F":"{print $1}'cut -d":" -f1 中提取文件名更容易阅读/理解
  • 好的,谢谢。主要问题是 sed 像循环一样更改每个文件中的时间戳。

标签: bash ubuntu awk sed


【解决方案1】:
sed "s|$line: .*|: $new|" file.yml

sed输出文件内容,不修改文件。

$line: .* 将匹配整行,因此它将删除它并将整行替换为: $new

如果你有 GNU sed,你可以使用 -i sed 参数来修改文件:

sed -i "s|$line: .*|$line: $new|" file.yml

或更好:

sed -i "s|\($line: \).*|\1$new|" file.yml

但是你不能同时读写同一个文件!

sub(/:.*/,"") 也似乎很奇怪——只需使用: 作为分隔符阅读,这就是 IFS 的用途。 while IFS=: read -r line ignore_the_rest; do ... done &lt;file.yml.

不是逐行替换每个文件上的文件,而是输出一个新的文件内容并放在目的地。

{
   IFS= read -r preserve_first_line
   printf "%s\n" "$preserve_first_line"
   while IFS=':' read -r line _; do
       new=$(git log -1 --pretty="format:%ct" "$line")
       echo "$line: $new"
   done
} < file.yml > new_file.yml
mv new_file.yml file.yml

如果你真的想做就地编辑,先缓存文件,这样你就不会同时对同一个文件进行读写。

readarray -t files < <(awk 'NR>1{sub(/:.*/,"");print $1}' file.yml)
for line in "${files[@]}"; do
    new=$(git log -1 --pretty="format:%ct" "$line")
    sed -i "s|\($line: \).*|\1$new|" file.yml
done

【讨论】:

    【解决方案2】:

    sed 自己逐行运行,不需要循环运行,就这样

    sed 's/\(^.*\): \(.*\)/echo \1: $(code_to_get_new_timestamp)/e' file.yml
    

    【讨论】:

      猜你喜欢
      • 2018-07-15
      • 1970-01-01
      • 2017-08-19
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      • 2013-02-21
      • 2013-11-15
      相关资源
      最近更新 更多