bash 如何使用bash替换多行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8694957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:14:15  来源:igfitidea点击:

how to replace multiple lines using bash?

linuxbashubuntureplaceline

提问by AlwynIsPat

I have a file with thousands of lines. I'm looking for help to modify multiple lines which i were to choose.

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

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

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

I need a bash command to detect "Filename" then change them to something like this:

我需要一个 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

And it will loop till all "Filename" have been changed.

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

采纳答案by Johnsyweb

This is a job for sed! From the GNU sedhomepage:

这是一份工作sed!从GNU sed主页:

Sed is typically used for extracting part of a file using pattern matching or substituting multiple occurrences of a string within a file.

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

Here is how you could do it:

以下是您可以这样做的方法:

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

Where:

在哪里:

  • /^Filename:/looks for lines starting with (^) the text 'Filename:'
  • s!search!replace!replaces 'search' with 'replace' where 'search' is a regular expression
  • \1is the string captured by the first matching group "\(...\)"
  • \2is the string captured by the second matching group "\(...\)"
  • /^Filename:/查找以 ( ^) 文本 'Filename:'开头的行
  • s!search!replace!用 'replace' 替换 'search',其中 'search' 是一个正则表达式
  • \1是第一个匹配组“ \(...\)”捕获的字符串
  • \2是第二个匹配组“ \(...\)”捕获的字符串

Demonstration:

示范:

$ 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!download.php?p=!' 
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

For tweaking this and for writing your own sedscripts, please consult the online documentation.

要对此进行调整并编写您自己的sed脚本,请参阅在线文档

回答by fge

This is one solution:

这是一种解决方案:

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

First try it by not putting it the ioption and pipe with less. Then re-add the i.

首先尝试不要将其放入i选项并使用less. 然后重新添加i.

回答by viraptor

Not in bash itself, but:

不是 bash 本身,而是:

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

回答by ChrisWue

You are looking for a tool called sed:

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

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

回答by SiegeX

Here are improved answers with awkand sed.

这里是改进的答案awksed

Unlike the other answers, these work independent of what the 'Filename:' path is. That is to say, if you change './debs/' to './myDebs/' it will still work. All they require is that '.deb' file is at the end of the path

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

Sed

sed

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

awk

awk

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

Input

输入

$ 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 Output

sed 输出

$ sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|download.php?p=|' ./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 Output

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

回答by potong

This might work for you:

这可能对你有用:

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