簡體   English   中英

在 shell 腳本中查找多行文本並使用正則表達式替換它

[英]Find multi-line text & replace it, using regex, in shell script

我試圖找到兩個連續行的模式,其中第一行是固定字符串,第二行有一部分 substring 我喜歡替換。

這將在 macOS 上的shbash中完成。

如果我手頭有一個可以對整個文本進行操作的正則表達式工具,這對我來說很容易。 但是,我發現的只是 bash 的簡單文本替換——它不適用於正則表達式,以及sed ,它是面向行的。

我懷疑我可以使用sed的方式首先找到匹配的第一行,然后如果它的模式也匹配,然后才尋找替換下一行,但我無法弄清楚這一點。

或者 macOS 上是否有其他工具可以讓我對整個文件或字符串進行基於正則表達式的搜索和替換? 也許使用 Python(安裝了 v2.7 和 v3)?

這是一個示例文本以及我喜歡它的修改方式:

  keyA
  value:474
  keyB
  value:474    <-- only this shall be replaced (follows "keyB")
  keyC
  value:474
  keyB
  value:474

現在,我想找出第一行是“keyB”而下一行是“value:474”的所有情況,然后將第二行替換為另一個值,例如“value:888”。

作為一個忽略行分隔符的正則表達式,我會這樣寫:

  • 搜索: (\bkeyB\n\s*value):474
  • 更換: $1:888

所以,基本上,我找到了 474 之前的模式,然后用相同的模式加上新的數字 888 替換它,從而保留了原來的縮進(它是可變的)。

您可以使用

sed -e '/keyB$/{n' -e 's/\(.*\):[0-9]*/\1:888/' -e '}' file
# Or, to replace the contents of the file inline in FreeBSD sed:
sed -i '' -e '/keyB$/{n' -e 's/\(.*\):[0-9]*/\1:888/' -e '}' file

詳情

  • /keyB$/ - 查找所有以keyB結尾的行
  • n - 清空當前模式空間並將下一行讀入其中
  • s/\(.*\):[0-9]*/\1:888/ - 查找直到最后的任何文本: + 零個或多個數字將該文本捕獲到第 1 組中,並替換為該組的內容和:888

{...}創建一個僅在滿足/keyB$/條件時才執行的塊。

請參閱在線sed演示

使用帶有-0777的 perl 單線掃描多行:

$ # inline edit:
$ perl -0777 -i -pe 's/\bkeyB\s*value):\d*/$1:888/' file.txt
$ # to stdout:
$ cat file.txt | perl -0777 -pe 's/\bkeyB\s*value):\d*/$1:888/'

在普通 bash 中:

#!/bin/bash

keypattern='^[[:blank:]]*keyB$'
valpattern='(.*):'
replacement=888

while read -r; do
    printf '%s\n' "$REPLY"
    if [[ $REPLY =~ $keypattern ]]; then
        read -r
        if [[ $REPLY =~ $valpattern ]]; then
            printf '%s%s\n' "${BASH_REMATCH[0]}" "$replacement"
        else
            printf '%s\n' "$REPLY"
        fi
    fi
done < file

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM