Bash: 找到一个模式并替换下面的内容
Bash: Find a pattern and replace what follows
我有一个如下所示的 .txt 文件:
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{4,5,12}}
BarBar Bar
HelloFoo {{6,5}}
我想在文件中找到字符串 'BarFooHello' 并将直接跟在 'BarFooHello' 之后的起始字符串 '{{' 和结束字符串 '}}' 之间的任何内容替换为 ' 12、12、12、12'。目标是获取文件这个文件末尾:
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{12,12,12,12}}
BarBar Bar
HelloFoo {{6,5}}
我如何在 Bash 中执行此操作? 我很想在 bash 中使用一个函数,该函数接受 1) 起始字符串 2)结束字符串,3) 应在其后执行修改的字符串,以及 4) 用于替换起始字符串和结束字符串之间存在的当前内容的字符串。
$ sed '/^BarFooHello/ s/{{.*}}/{{12,12,12,12}}/' file.txt
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{12,12,12,12}}
BarBar Bar
HelloFoo {{6,5}}
工作原理
sed
遍历文件中的每一行。
/^BarFooHello/
这只选择以 BarFooHello
.
开头的行
s/{{.*}}/{{12,12,12,12}}/
在那些选定的行上,这将替换该行中第一个 {{
和最后一个 }}
之间的所有内容,并将其替换为 {{12,12,12,12}}
.
纯Bash:
#!/bin/bash
repl () {
line=""
str=""
pre=""
suf=""
values=""
if [[ $line =~ ^$str ]]; then
line="${line/%$pre*$suf/$pre$values$suf}"
fi
echo "$line"
}
while read line; do
repl "$line" BarFooHello "{{" "}}" 12,12,12,12
done < file
repl() 函数一次处理一行文本,并且仅当该行与字符串匹配时才进行替换。
Bash 没有反向引用机制,这需要冗余。 ${line/%$pre*$suf/$pre$values$suf}
用前缀字符串、新值和后缀字符串替换从前缀字符串到后缀的所有内容。
使用 sed,您可以:
funct ()
{
start= # "BarFooHello"
begin= # "{{"
end= # "}}"
string= # "12,12,12,12"
file= # The file to perform the replacement
sed "s/^$start $begin[[:print:]]*$end/$start $begin$string$end/g" $file # Sensitive to 3 spaces
# or
sed "s/^$start\(\ *\)$begin[[:print:]]*$end/$start$begin$string$end/g" $file # Preserve the amount of spaces
}
并像那样使用:
funct "BarFooHello" "{{" "}}" "12,12,12,12" test.txt
我有一个如下所示的 .txt 文件:
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{4,5,12}}
BarBar Bar
HelloFoo {{6,5}}
我想在文件中找到字符串 'BarFooHello' 并将直接跟在 'BarFooHello' 之后的起始字符串 '{{' 和结束字符串 '}}' 之间的任何内容替换为 ' 12、12、12、12'。目标是获取文件这个文件末尾:
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{12,12,12,12}}
BarBar Bar
HelloFoo {{6,5}}
我如何在 Bash 中执行此操作? 我很想在 bash 中使用一个函数,该函数接受 1) 起始字符串 2)结束字符串,3) 应在其后执行修改的字符串,以及 4) 用于替换起始字符串和结束字符串之间存在的当前内容的字符串。
$ sed '/^BarFooHello/ s/{{.*}}/{{12,12,12,12}}/' file.txt
HelloWorld (3,4,5)
FooFooFoo {34,34,34}{23,1,2}
BarFooHello {{12,12,12,12}}
BarBar Bar
HelloFoo {{6,5}}
工作原理
sed
遍历文件中的每一行。
/^BarFooHello/
这只选择以
BarFooHello
. 开头的行
s/{{.*}}/{{12,12,12,12}}/
在那些选定的行上,这将替换该行中第一个
{{
和最后一个}}
之间的所有内容,并将其替换为{{12,12,12,12}}
.
纯Bash:
#!/bin/bash
repl () {
line=""
str=""
pre=""
suf=""
values=""
if [[ $line =~ ^$str ]]; then
line="${line/%$pre*$suf/$pre$values$suf}"
fi
echo "$line"
}
while read line; do
repl "$line" BarFooHello "{{" "}}" 12,12,12,12
done < file
repl() 函数一次处理一行文本,并且仅当该行与字符串匹配时才进行替换。
Bash 没有反向引用机制,这需要冗余。 ${line/%$pre*$suf/$pre$values$suf}
用前缀字符串、新值和后缀字符串替换从前缀字符串到后缀的所有内容。
使用 sed,您可以:
funct ()
{
start= # "BarFooHello"
begin= # "{{"
end= # "}}"
string= # "12,12,12,12"
file= # The file to perform the replacement
sed "s/^$start $begin[[:print:]]*$end/$start $begin$string$end/g" $file # Sensitive to 3 spaces
# or
sed "s/^$start\(\ *\)$begin[[:print:]]*$end/$start$begin$string$end/g" $file # Preserve the amount of spaces
}
并像那样使用:
funct "BarFooHello" "{{" "}}" "12,12,12,12" test.txt