[英]pattern match and add line at the end or start of a line in a text file using sed
[英]Using sed to add text after a pattern, but the added text comes from a list file
如何使用 sed 定位字符串,并在字符串后添加另一个文件中的文本?
文件 1:
stage ('Clone Repo31') {
steps {
git credentialsId: '', url: '/stash/scm/'
}
}
stage ('Zip Repo31') {
steps {
sh"""
tar --exclude='*.tar' -cvf .tar *
"""
}
}
steps {
git credentialsId: '', url: '/stash/scm/'
}
}
stage ('Zip Repo32') {
steps {
sh"""
tar --exclude='*.tar' -cvf .tar *
"""
}
}
文件2:
randomRepo.git
differentRandomRepo.git
我希望能够使用 sed 读取第二个文件,并在每次出现 stash/scm/ 后添加第二个文件中每一行的内容
期望的输出:
stage ('Clone Repo31') {
steps {
git credentialsId: '', url: '/stash/scm/randomRepo.git'
}
}
stage ('Zip Repo31') {
steps {
sh"""
tar --exclude='*.tar' -cvf .tar *
"""
}
}
steps {
git credentialsId: '', url: '/stash/scm/differentRandomRepo.git'
}
}
stage ('Zip Repo32') {
steps {
sh"""
tar --exclude='*.tar' -cvf .tar *
"""
}
}
这可以用sed完成吗? 我在从列表文件中读取它时遇到问题,这很令人困惑,因为它有很多斜线。 我已经能够使用普通的 sed 替换,但我不知道如何通过读取另一个文件来进行替换。
下面我将介绍一个几乎纯sed
解决方案。
sed
有一个r
命令来读取文件,所以原则上你可以使用它来读取file2
。 但是,没有后续命令会影响从文件中读取的行,因此我想不出任何有效地使用r
命令来执行您要求的方法。
但是,如果file1
和file2
都在sed
输入中给出,则解决方案是可能的。
下面,为了区分这两个文件,我放了一个标记行( -----
),我认为理所当然不在file2
; 但是,它可以位于file1
中的任何位置而不会产生任何问题。
cat file2 <(echo '-----') file1 | sed -f script.sed
其中script.sed
如下:
1{ # only on line 1
:a # begin while
/-----/!{ # while the line does not contain the marker
N # append the following line
ba # end while
} # here the pattern space is a multiline containing the list
s/\n-----// # remove the last newline and the marker
h # put the multiline in the hold space
d # delete, as we don't want to print anything so far
} # that's it, lines from 1 to the marker are processed
/stash\/scm\//{ # for lines matching this pattern
G # we append the full hold space
s/'\n\([^\n]*\)/\1'/ # and position the first entry in the list appropriately
x # then we swap pattern and hold space
s/[^\n]*\n// # remove the first element of the list
x # and swap again
} # now the hold space has one item less
这是一个bash
脚本,它使用sed
并逐行读取 File_2(包含替换的文件),从而一次读取一个替换。 然后我用 sed 脚本替换了 File_1 中的行。
while IFS= read -r line; do
sed -i "0,/\/stash\/scm\/'/{s|/stash/scm/'|/stash/scm/${line}'|}" File_1.txt
done < File_2.txt
一些技巧用于做到这一点:
sed '0,/Apple/{s/Apple/Banana/}' input_filename
只用字符串Banana
替换字符串Apple
文件名中的第一次出现sed
脚本使用双引号以允许变量扩展${line}
s|/stash/scm/'|
包含搜索参数的结尾单引号字符'
来完成的s|/stash/scm/'|
while IFS= read -r line; do
echo $line
done < File_2.txt
你想要像这样的线条
sed 's#'/stash/scm/'#&something_from_file2#' file1
你可以用这些线
# Note:
# / is not a delimiter, but part of the path
# % is the delimiter in the current sed-command
# # is the delimiter in the generated command.
sed 's%.*%s#/stash/scm/#\&&#%' file2
您可以即时生成这些命令并在 file1 上执行它们。
sed -f <(sed 's%.*%s#/stash/scm/#\&&#%' file2) file1
还剩一个问题。 这两个命令都将替换所有匹配项。
我将使用比赛后给出的单引号。 当在/stash/scm/'
的单引号之前放置某些内容时,这与查找包含引号的/stash/scm/'
字符串时的匹配文件不同。
你想生成像
s#(/stash/scm/)(')#\1randomRepo.git\2#
s#(/stash/scm/)(')#\1differentRandomRepo.git\2#
每个替换应该只执行一次,因此我们使用选项-z
将 file2 视为一个长行:
sed -rzf <(sed 's%.*%s#(/stash/scm/)('\'')#\\1&\\2#%' file2) file1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.