Bash 通过脚本进行字符串操作

Bash 通过脚本进行字符串操作,bash,shell,Bash,Shell,我试图在&DEST=和下一个&之间获取一个子字符串或换行符。 例如: MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546 在此,我需要提取“SFO” MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546 在这里我需要摘录“SANFRANSISCO” MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE 在这里我需要摘录“SANJOSE” 我正在逐行读取文件,我需要更新&DEST=

我试图在
&DEST=
和下一个
&
之间获取一个子字符串或换行符。 例如:

  • MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546

    在此,我需要提取“SFO”

  • MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546

    在这里我需要摘录“SANFRANSISCO”

  • MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE

    在这里我需要摘录“SANJOSE”

  • 我正在逐行读取文件,我需要更新
    &DEST=
    之后的文本并将其放回文件中。文本的修改是用X字符屏蔽dest值

    因此,SFO应替换为XXX。 SANJOSE应替换为XXXXXXX

    输出:
    MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=xxxxxxxxxxx&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX

    请让我知道如何在脚本中实现这一点(最好是shell或bash脚本)

    谢谢

    $ cat file
    MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=PORTORICA
    MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE
    $ sed -E 's/^.*&DEST=([^&]*)[&]*.*$/\1/' file
    SFO
    PORTORICA
    SANFRANSISCO
    SANJOSE
    
    应该这样做

    应该这样做

    用相同数量的X取代机场

    让我们考虑这个测试文件:

    $ cat file
    MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE
    
    要将
    &DEST=
    之后的字符串替换为长度相等的
    X
    ,请使用GNU-sed:

    $ sed -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file
    MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=XXXXXXXXXXXX&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX
    
    要就地替换文件,请执行以下操作:

    sed -i -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file
    
    以上内容已通过GNU sed进行了测试。对于BSD(OSX)sed,请尝试:

    sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    sed -i '' -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    或者,要使用BSD(OSX)sed进行就地更改,请尝试:

    sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    sed -i '' -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    如果出于某种原因,必须使用shell逐行读取文件:

    while IFS= read -r line
    do
       echo "$line" | sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta
    done <file
    
    • -E

      这告诉sed使用扩展正则表达式(ERE)。这样做的好处是需要较少的反斜杠来逃避问题

    • :a

      这将创建一个标签
      a

    • s/(“$search\u str”X*)[^X&]/\1X/

      这将查找
      $search\u str
      ,后跟任意数量的
      X
      ,后跟任何不是
      X
      &
      的字符。由于parens,除最后一个字符外的所有字符都保存到组1中。此字符串由组1替换,表示为
      \1
      X

    • ta

      在sed中,
      t
      是一个
      test
      命令。如果进行了替换(意味着某些字符需要替换为
      X
      ),则测试结果为true,在这种情况下,
      ta
      告诉sed跳转到标签
      a

      此测试和跳转会导致替换根据需要重复多次

    用一个sed命令替换多个标记 原问题的答案 使用外壳 工作原理:

    • ${s}*&DEST=}
      是前缀删除。这将删除第一次出现的
      &DEST=
      之前的所有文本

    • ${s%%&*}
      是后缀删除。它删除从第一个
      &
      到字符串末尾的所有文本

    使用awk 工作原理:

    • -F'[=\n]'

      这告诉awk将等号或换行符作为字段分隔符

    • $1==“DEST”{print$2}

      如果第一个字段是DEST,则打印第二个字段

    • RS='&'

      这将记录分隔符设置为
      &

    用相同数量的X取代机场

    让我们考虑这个测试文件:

    $ cat file
    MYREQUESTISTO8764GETTHIS&DEST=SFO&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=SANFRANSISCO&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=SANJOSE
    
    要将
    &DEST=
    之后的字符串替换为长度相等的
    X
    ,请使用GNU-sed:

    $ sed -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file
    MYREQUESTISTO8764GETTHIS&DEST=XXX&ORIG=6546
    MYREQUESTISTO8764GETTHIS&DEST=XXXXXXXXXXXX&ORIG=6546
    MYREQUESTISTO8764GETTHISWITH&DEST=XXXXXXX
    
    要就地替换文件,请执行以下操作:

    sed -i -E ':a; s/(&DEST=X*)[^X&]/\1X/; ta' file
    
    以上内容已通过GNU sed进行了测试。对于BSD(OSX)sed,请尝试:

    sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    sed -i '' -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    或者,要使用BSD(OSX)sed进行就地更改,请尝试:

    sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    sed -i '' -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta file
    
    如果出于某种原因,必须使用shell逐行读取文件:

    while IFS= read -r line
    do
       echo "$line" | sed -Ee :a -e 's/(&DEST=X*)[^X&]/\1X/' -e ta
    done <file
    
    • -E

      这告诉sed使用扩展正则表达式(ERE)。这样做的好处是需要较少的反斜杠来逃避问题

    • :a

      这将创建一个标签
      a

    • s/(“$search\u str”X*)[^X&]/\1X/

      这将查找
      $search\u str
      ,后跟任意数量的
      X
      ,后跟任何不是
      X
      &
      的字符。由于parens,除最后一个字符外的所有字符都保存到组1中。此字符串由组1替换,表示为
      \1
      X

    • ta

      在sed中,
      t
      是一个
      test
      命令。如果进行了替换(意味着某些字符需要替换为
      X
      ),则测试结果为true,在这种情况下,
      ta
      告诉sed跳转到标签
      a

      此测试和跳转会导致替换根据需要重复多次

    用一个sed命令替换多个标记 原问题的答案 使用外壳 工作原理:

    • ${s}*&DEST=}
      是前缀删除。这将删除第一次出现的
      &DEST=
      之前的所有文本

    • ${s%%&*}
      是后缀删除。它删除从第一个
      &
      到字符串末尾的所有文本

    使用awk 工作原理:

    • -F'[=\n]'

      这告诉awk将等号或换行符作为字段分隔符

    • $1==“DEST”{print$2}

      如果第一个字段是DEST,则打印第二个字段

    • RS='&'

      这将记录分隔符设置为
      &

    使用GNU bash:

    while IFS= read -r line; do
      [[ $line =~ (.*&DEST=)(.*)((&.*|$)) ]] && echo "${BASH_REMATCH[1]}fooooo${BASH_REMATCH[3]}"
    done < file
    
    而IFS=read-r行;做
    [[$line=~(.*&DEST=)(.*)(&.*.$)]]&&echo“${BASH_重新匹配[1]}foooooo${BASH_重新匹配[3]}”
    完成<文件
    
    输出:

    MYREQUESTISTO8764GETTHIS&DEST=fooooo&ORIG=6546 MYREQUESTISTO8764GETTHIS&DEST=fooooo&ORIG=6546 MYREQUESTISTO8764GETTHISWITH&DEST=fooooo MYREQUESTISTO8764GETTHIS&DEST=foooooo&ORIG=6546 MYREQUESTISTO8764GETTHIS&DEST=Foooooo&ORIG=6