簡體   English   中英

Bash - 從文件中刪除特定的文本塊

[英]Bash - remove specific textblock from file

我想從文件中刪除特定的文本塊。 我想找到要刪除的文本塊的開頭,並刪除所有內容,直到找到特定模式。

要搜索的示例字符串:

\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component and then follow many more characters with various special characters -- / ending with another \n---\n that I dont want to remove

我想刪除所有內容,從這個字符串匹配開始\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component

所以基本上,找到模式\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component並刪除所有內容,直到我匹配下一個\n---\n

預計 output 將是:

\n---\n that I dont want to remove

我用 sed 試過的東西:

sed 's/\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component.*\n---\n//g'

我用 grep 試過的東西:

echo $string  | grep -Ewo "\\\n---\\\n# Source: app/templates/deployment.yaml\\\n# template file\napiVersion: apps/v1\\\nkind: Deployment\nmetadata:\\\n name: component"

沒有什么真正有效。 是否有任何 bash 向導可以提供幫助?

使用文字字符串來避免必須轉義任何字符並假設您的目標字符串在輸入中只存在一次:

$ cat tst.sh
#!/usr/bin/env bash

awk '
    BEGIN {
        begStr  = ARGV[1]
        endStr  = ARGV[2]
        ARGV[1] = ARGV[2] = ""
        begLgth = length(begStr)
    }
    begPos = index($0,begStr) {
        tail = substr($0,begPos+begLgth)
        endPos = begPos + begLgth + index(tail,endStr) - 1
        print substr($0,1,begPos-1) substr($0,endPos)
    }
' \
    '\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component' \
    '\n---\n' \
    "${@:--}"

$ ./tst.sh file
\n---\n that I dont want to remove

對於您展示的樣品,請嘗試遵循awk代碼。 搜索字符串\\n---\\n# Source: app\/templates\/deployment.yaml\\n# template file\\napiVersion: apps\/v1\\nkind: Deployment\\nmetadata:\\n name: component並將字段分隔符設置為\\\\n---\\\\n然后打印該行的最后一個字段。

awk -v OFS="\\\\n---\\\\n " -F'\\\\n---\\\\n ' '
/\\n---\\n# Source: \
app\/templates\/deployment.yaml\\n# template \
file\\napiVersion: apps\/v1\\nkind: Deployment\
\\nmetadata:\\n name: component/{
  print OFS $NF
}
'  Input_file

Output 將如下:

\n---\n that I dont want to remove

您需要轉義正則表達式中的反斜杠以逐字匹配它們。

如果\\n---\\n123456789\\n---\\n之間的部分不能包含另一個- ,您可以使用

sed 's/\\n---\\n123456789[^-]*\\n---\\n//g'

這個假設是必要的,因為sed不支持非貪婪量詞,並且.*將匹配到最后一個\\n---\\n ,而不是下一個。

所以基本上,找到模式\n---\n123456789並刪除所有內容,直到我匹配下一個\n---\n

使用 gnu-awk 通過將\n---\n設置為記錄分隔符(非正則表達式方法)可能會更簡單:

s='aaa aaa\n---\n123456789 hha faewb\n---\naaaaaa\n---\n67891 0238\n---\nbbbf bb'
awk -v RS='\\\\n---\\\\n' '$1 != 123456789 {ORS=RT; print}' <<< "$s"

aaa aaa\n---\naaaaaa\n---\n67891 0238\n---\nbbbf bb

這可能對您有用(GNU sed):

sed 'N;/\n---$/!{P;D};:a;N;//!ba
     s~\n---\n# Source: app/templates/deployment.yaml\n# template file\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: component.*~\n---~' file

打開兩行 window 並且如果 window 中的第二行不匹配\n---打印/刪除第一行並重復。

如果第二行匹配\n--- ,收集任何后續行,直到進行另一個匹配,如果后續行也匹配所需的字符串,則刪除所有行,直到第二個匹配。

否則正常打印行。

注意 這不適合連續兩個這樣的比賽。

暫無
暫無

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

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