如果文件中的兩行都符合某種模式,如何將它們連接起來?

如果文件中的兩行都符合某種模式,如何將它們連接起來?

我有一個包含多行的文件,如果它們都符合特定模式,我想將它們連接起來。

我知道我可以找到適合該模式的行並使用以下命令獲取下一行:

grep -E -A1 'Pattern' filename

但是我如何檢查下一行是否也符合該模式以及如何將兩者連接起來?

例如,我有一個這樣的文件:

Hello
i
am
John
Smith

範例模式可能如下:

'^[A-Z][a-z]+'

因此,在這種情況下,如果行都以大寫字母開頭,我想合併這些行。

我想要實現的輸出是:

Hello
i
am 
John Smith

答案1

/^[A-Z][a-z]+/{
  :a
  N
  /\n[A-Z][a-z]+/{
    s/\n/ /
    b a
  }
}

將其另存為join.sed並執行:sed -Ef join.sed file

如果該行與模式匹配,我們將啟動一個循環,將下一行附加到模式空間,並用空格替換換行符,只要該行也與模式匹配。

對於 GNU Sed,你可以將其折疊成一行:

sed -E '/^[A-Z][a-z]+/{:a;N;/\n[A-Z][a-z]+/{s/\n/ /;b a}}' file

或者,一個 Awk 腳本join.awk,其模式應為p

{
    if($0~p)c+=1
    else c=0
    printf "%s%s", (c>1 ? " " : ors), $0
    ors=ORS
}
END{print ""}

執行:awk -f join.awk p='^[A-Z][a-z]+' file

答案2

使用sed空字元作為分隔符號 ( -z):

$ sed -z 's/\([A-Z][a-z]\+\)\n\([A-Z][a-z]\+\)/\1 \2/'
Hello
i
am
John Smith

答案3

使用 Raku(以前稱為 Perl_6)

raku -e 'given lines.join("\n") { S/ $<first>=[<upper><lower>+] \n $<last>=[<upper><lower>+] /$<first> $<last>/.put};'

輸入範例:

Hello
i
am
John
Smith
goodbye

範例輸出:

Hello
i
am
John Smith
goodbye

上面是用 Raku(Perl 語言家族的成員)寫的解。資料given以 的形式傳送給 Raku lines,但由於 Raku 的lines例行自動剪切輸入,資料會join以換行符號進行 -ed。雖然這看起來有點複雜,但優點是 Raku 的lines例程可以延遲讀取數據,這意味著上面的程式碼應該記憶體效率高。

Raku 實作了一種S///「非破壞性」運算符,它與熟悉的s///運算符類似(如果不相同)(Raku 也有該運算符)。資本運營S商有一個優勢,那就是“保留原始字串完整併返回結果字串而不是 $/ (匹配變數)。”

在運算符的匹配(左)一半內S///命名捕獲被雇用。正規表示式引擎首先搜尋[<upper><lower>+]並將其指派給命名的 capture $<first>,然後搜尋一個\n(換行符),最後搜尋另一個[<upper><lower>+],這次將其指派給命名的 capture $<last>。最後,在運算符的替換(右)半部分中S///,兩個命名捕獲$<first> $<last>用於替換左側匹配,儘管一個空間和沒有\n之間的換行符。

完成同樣事情的另一種方法如下。該程式碼省略了命名捕獲,而是使用<(\n)>從匹配對像中刪除除捕獲標記內的內容之外的所有內容<(…)>。然後在替換中,\n空格替換:

raku -e 'put S/ [<upper><lower>+] <(\n)> [<upper><lower>+] / / given lines.join("\n");'  

[注意,上面的程式碼只會將George\nHerbert\nWalker\nBush4 行折疊成 3 行 ( George Herbert\nWalker\nBush)。如果您希望在一行上傳回所有按行連續出現的情況[<upper><lower>+],請隨時發布該問題]。

https://docs.raku.org/language/regexes#S///_non-breaking_substitution
https://docs.raku.org/language/regexes#index-entry-regex__Named_captures-Named_captures
https://raku.org

相關內容