简体   繁体   English

重击:找到一个模式并替换以下内容

[英]Bash: Find a pattern and replace what follows

I have a .txt file that looks like this: 我有一个.txt文件,看起来像这样:

HelloWorld    (3,4,5)
FooFooFoo     {34,34,34}{23,1,2}
BarFooHello   {{4,5,12}}
BarBar        Bar
HelloFoo      {{6,5}}  

I want to find the string 'BarFooHello' on the file and replace whatever is in between the starting string '{{' that directly follows 'BarFooHello' and the ending string '}}' by '12,12,12,12'. 我想在文件上找到字符串“ BarFooHello”,并将“ BarFooHello”之后的起始字符串“ {{”和结尾字符串“}}”之间的内容替换为“ 12,12,12,12”。 The goal is to obtain a file this file at the end: 目标是在此文件的最后获取一个文件:

HelloWorld    (3,4,5)
FooFooFoo     {34,34,34}{23,1,2}
BarFooHello   {{12,12,12,12}}
BarBar        Bar
HelloFoo      {{6,5}}  

How can I do this in Bash? 我如何在Bash中做到这一点? I would love to just have a function in bash that takes 1) the starting string 2) the ending string, 3) the string after which the modification should be performed and 4) the string to put in place of the current stuff that exist in between the starting string and the ending string. 我很想在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}}  

How it works 这个怎么运作

sed loops over every line in the file. sed遍历文件中的每一行。

  • /^BarFooHello/

    This selects only lines that begin with BarFooHello . 这仅选择以BarFooHello开头的BarFooHello

  • s/{{.*}}/{{12,12,12,12}}/

    On those selected lines, this substitutes everything between the first {{ and the last }} on that line and replaces it with {{12,12,12,12}} . 在这些选定的行上,这将替换该行的第一个{{和最后一个}}之间的所有内容,并将其替换为{{12,12,12,12}}

Using sed, you could have : 使用sed,您可能会:

funct ()
{
start=$1  # "BarFooHello"
begin=$2  # "{{"
end=$3    # "}}"
string=$4 # "12,12,12,12"
file=$5   # 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\1$begin$string$end/g"  $file  # Preserve the amount of spaces
}

and used like that : 并这样使用:

funct "BarFooHello" "{{" "}}" "12,12,12,12" test.txt

Pure Bash: 纯重击:

#!/bin/bash

repl () {
    line="$1"
    str="$2"
    pre="$3"
    suf="$4"
    values="$5"

    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

The repl() function works on one line of text at a time, and replaces only if the line matches the string. repl()函数一次只能处理一行文本,并且仅在该行与字符串匹配时才替换。

Bash has no mechanism for back-references, which necessitates redundancy. Bash没有用于反向引用的机制,因此需要冗余。 ${line/%$pre*$suf/$pre$values$suf} replaces everything from the prefix string through the suffix with the prefix string, new values and suffix string. ${line/%$pre*$suf/$pre$values$suf}用前缀字符串,新值和后缀字符串替换从前缀字符串到后缀的所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM