如何使用bash替换多行?

时间:2012-01-01 19:23:50

标签: linux bash ubuntu replace line

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

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命令来检测“Filename”,然后将它们更改为:

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

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

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

这是一个解决方案:

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

首先尝试一下,不要将i选项和管道less放在一起。然后重新添加i

答案 2 :(得分:0)

不是bash本身,但是:

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

以下是awksed的改进答案。

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

桑达

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

答案 5 :(得分:0)

这可能对您有用:

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