【问题标题】:how to replace multiple lines using bash?如何使用bash替换多行?
【发布时间】:2012-01-31 11:18:09
【问题描述】:

我有一个包含数千行的文件。我正在寻求帮助来修改我要选择的多行。

Package: com.xyz.abc
Version: 1.0
Filename: ./debs/abc.deb

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/def.deb

我需要一个 bash 命令来检测“文件名”,然后将它们更改为如下内容:

Package: com.xyz.abc
Version: 1.0
Filename: ./debs/download.php?p=abc

Package: com.xyz.def
Version: 1.0.0-1
Filename: ./debs/download.php?p=def

它会循环直到所有“文件名”都被更改。

【问题讨论】:

  • 您应该首先展示您尝试过的内容,编写的代码,然后才寻求帮助。你想要鱼还是会钓鱼?

标签: linux bash ubuntu replace line


【解决方案1】:

这是一种解决方案:

perl -pi -e '/^Filename:/ and s,debs/([^.]+)\.deb\s*$,debs/download.php?p=$1,' thefile

首先尝试它,不要把它放在i 选项和less 管道上。然后重新添加i

【讨论】:

    【解决方案2】:

    不在 bash 本身,而是:

    sed 's#Filename: \./debs/\(.*\)\.deb#Filename: ./debs/download.php?p=\1#' < the_file
    

    【讨论】:

      【解决方案3】:

      您正在寻找一个名为sed的工具:

      sed -e "s|^(Filename: ./debs/)(.+).deb|\1download.php?p=\2|" < yourfile
      

      【讨论】:

        【解决方案4】:

        这是sed 的工作!来自GNU sed主页:

        Sed 通常用于使用模式匹配或替换文件中多次出现的字符串来提取文件的一部分。

        你可以这样做:

        sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' /path/to/input > /path/to/output
        

        地点:

        • /^Filename:/ 查找以 (^) 文本“文件名:”开头的行
        • s!search!replace! 将 'search' 替换为 'replace' 其中 'search' 是正则表达式
        • \1 是第一个匹配组“\(...\)”捕获的字符串
        • \2 是第二个匹配组“\(...\)”捕获的字符串

        演示:

        $ echo 'Package: com.xyz.abc
        Version: 1.0
        Filename: ./debs/abc.deb
        
        Package: com.xyz.def
        Version: 1.0.0-1
        Filename: ./debs/def.deb' | sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' 
        Package: com.xyz.abc
        Version: 1.0
        Filename: ./debs/download.php?p=abc
        
        Package: com.xyz.def
        Version: 1.0.0-1
        Filename: ./debs/download.php?p=def
        

        要对此进行调整并编写自己的sed 脚本,请咨询online documentation

        【讨论】:

        • @downvoter:为什么?如果我的回答有问题,请指出。
        【解决方案5】:

        以下是awksed 的改进答案。

        与其他答案不同,这些工作独立于“文件名:”路径是什么。也就是说,如果将 './debs/' 更改为 './myDebs/' 它仍然可以工作。他们所需要的只是“.deb”文件位于路径的末尾

        Sed

        sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile
        

        awk

        awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile
        

        输入

        $ cat ./infile
        Package: com.xyz.abc
        Version: 1.0
        Filename: ./debs/abc.deb
        
        Package: com.xyz.def
        Version: 1.0.0-1
        Filename: ./MyDebs/def.deb
        

        sed 输出

        $ sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile
        Package: com.xyz.abc
        Version: 1.0
        Filename: ./debs/download.php?p=abc
        
        Package: com.xyz.def
        Version: 1.0.0-1
        Filename: ./MyDebs/download.php?p=def
        

        awk 输出

        $ awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile
        Package: com.xyz.abc
        Version: 1.0
        Filename: ./debs/download.php?p=abc
        
        Package: com.xyz.def
        Version: 1.0.0-1
        Filename: ./MyDebs/download.php?p=def
        

        【讨论】:

          【解决方案6】:

          这可能对你有用:

           sed '/^Filename:/s/\([^/]*\)\.[^.]*$/download.php?p=\1/' file
          

          【讨论】:

            猜你喜欢
            • 2020-09-22
            • 1970-01-01
            • 2021-11-11
            • 2021-09-12
            • 2012-10-22
            • 2021-11-14
            • 2013-09-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多