【问题标题】:Edit file in unix using SED使用 SED 在 unix 中编辑文件
【发布时间】:2012-04-19 21:08:28
【问题描述】:

我在 UNIX 中有 file1.txt 如下

[Section A]
$param1=value1
$param2=value2

[Section B]
$param1=value1
$param2=value2
$param3=value3

我想以编程方式将 B 部分中的 value2 编辑为 new_value2

[Section A]
$param1=value1
$param2=value2

[Section B]
$param1=value1
$param2=new_value2
$param3=value3

知道执行此操作的 unix 命令应该是什么(使用 sed 吗?)?

非常感谢。

【问题讨论】:

  • 这取决于您需要的灵活性以及文件上的其他限制。例如,参数值对在文件中是唯一的,还是仅在一个部分中唯一?
  • @merlin2011:我认为他发布了一个很好的例子......

标签: linux file bash unix sed


【解决方案1】:
sed -ie '/^\[Section B\]$/,/^$/s/^\$param2=value2$/$param2=new_value/' foo.txt

编辑: 上面的例子对旧值和空格字符非常严格。我添加了另一个可能更合适的示例。 sed 脚本由一个命令组成,并以以下地址范围为前缀:

/^\[Section B\]/,/^\[.*\]/

地址范围由两个用逗号分隔的正则表达式组成,并将以下命令限制为从第一个地址匹配的行开始,一直持续到第二个地址匹配(包括)。

s/^\(\$param2[ \t]*=[ \t]*\).*$/\1new_value/

替换命令用范围进行实际替换。一切都在一起:

sed -ie '/^\[Section B\]/,/^\[.*\]/s/^\(\$param2[ \t]*=[ \t]*\).*$/\1new_value/' foo.txt

【讨论】:

  • 替换前面的 /^$/ 的目的是什么?
  • @barsju:前两个正则表达式属于同一类。这意味着:在从[Section B] 到下一个空行的范围内,进行替换。如果将[Section B] 替换为[Section A],则只会替换第一个匹配项。
  • 嗨 nosid,这几乎是完美的,但这里假设 param2 在原始文件中始终具有 value2,如何使其灵活,即 param2 在更改之前可以是任何值?非常感谢!
【解决方案2】:

如果 Perl 适合你,你可以这样做:

perl -pe '$f=1 if(/\[Section B\]/);
          s/^\$param2=value2$/\$param2=new_value2/ if($f);' < file

See it

【讨论】:

    【解决方案3】:

    如果您需要 awk 中的解决方案:

    nawk -F= '{if($0~/Section B/){print;getline;print;getline;gsub(/value2/,"value9",$2);print}else print}' file3
    

    在下面测试:

    pearl.274> cat file3
    [section A]
    $param1=value1
    $param2=value2
    
    [Section B]
    $param1=value1
    $param2=value2
    $param3=value3
    pearl.275> nawk -F= '{if($0~/Section B/){print;getline;print;getline;gsub(/value2/,"new_value2",$2);print}else print}' file3
    [section A]
    $param1=value1
    $param2=value2
    
    [Section B]
    $param1=value1
    $param2 new_value2 
    $param3=value3
    pearl.276> 
    

    【讨论】:

    • 在代码中硬编码文件的确切结构是一个非常可怕的想法。
    • 可怕的想法......这是否意味着它的错误答案。OP 的目的已经解决......你不这么认为吗?如果 OP 提到 param2 可以在 B 节之后的任何地方,我猜这将是错误的。但是 OP 没有这样做。
    • 这正是为什么它是一个坏主意的原因......它似乎起作用了,直到有一个微小的变化,突然......“嗯?这是怎么回事?”
    【解决方案4】:

    解析文件、执行编辑和重构的TXR程序:

    @;
    @; grab four comand line arguments
    @;
    @(next :args)
    @(cases)
    @file
    @new_section
    @new_param
    @new_value
    @(or)
    @(throw "arguments needed: file section param value")
    @(end)
    @;
    @; hash table mapping sections to assocation lists of values
    @;
    @(bind sec @(hash :equal-based))
    @;
    @; parse file, obtaining list of section names and filling in
    @; section hash with an associ list of entries.
    @;
    @(next file)
    @(collect)
    [Section @secname]
    @  (collect)
    $@param=@val
    @  (until)
    
    @  (end)
    @(do (set [sec secname] [mapcar cons param val]))
    @(end)
    @;
    @; now edit
    @;
    @(do (let ((sec-entries [sec new_section]))
           (if (null sec-entries)
             (push new_section secname))
           (set [sec new_section] (acons-new new_param new_value sec-entries))))
    @;
    @; now regurgitate file
    @;
    @(do (each* ((s secname)
                 (ent (mapcar (op sec) s)))
           (format t "[Section ~a]\n" s)
           (each ((e ent))
             (format t "$~a=~a\n" (car e) (cdr e)))
           (put-string "\n")))
    

    测试运行:

    # edit section B param2 to new_value2
    
    $ txr config.txr config.txt B param2 new_value2
    [Section A]
    $param1=value1
    $param2=value2
    
    [Section B]
    $param1=value1
    $param2=new_value2
    $param3=value3
    
    # add new parameter x with value y to section A
    
    $ txr config.txr config.txt A x y
    [Section A]
    $x=y
    $param1=value1
    $param2=value2
    
    [Section B]
    $param1=value1
    $param2=value2
    $param3=value3
    
    # add new section with new parameter
    
    $ txr config.txr config.txt foo bar xyzzy
    [Section foo]
    $bar=xyzzy
    
    [Section A]
    $param1=value1
    $param2=value2
    
    [Section B]
    $param1=value1
    $param2=value2
    $param3=value3
    

    读者练习:实现参数/值对的删除。

    【讨论】:

      【解决方案5】:

      非常简单的解决方案。

      ex file1.txt <<"INPUT"
      /Section B
      /param2
      s/value2/new_value2/
      :x
      INPUT
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 2011-12-17
        • 2011-05-26
        • 2022-07-12
        • 2016-02-19
        • 1970-01-01
        • 2010-10-17
        相关资源
        最近更新 更多