Sed

sed 使用關鍵字、隨機詞和已知符號匹配和重新格式化字元串

  • September 17, 2022

經過幾個小時試圖讓我的sed查詢工作,我即將放棄!

我有以下字元串,從原始碼中提取 - 目的是為許多舊的和未記錄的程式碼生成原型。例如:

function foo(bar=1);

我想最終得到類似的東西:

function foo(
   bar=1)

我想匹配所有function 以隨機字母數字(和 - 和 _)單詞開頭的行,並添加換行符和製表符sed

我的問題是 sed 預設情況下是貪婪的,由於正則表達式貪婪,我無法sed在第一個換行符之後添加換行符。(

所以像這樣的硬編碼工作:

echo 'function foo(bar=true)' | sed 's:\(function foo(\)\(.*\):\1\n\t\2:g'

這給了我預期的輸出:

function foo(
   bar=true)

我可以將其修改為以下內容,在字元後添加換行符(

echo 'function foo(bar=true)' | sed 's:\(function.*(\)\(.*\):\1\n\t\2:g'

這給出了與以前相同的預期結果 - 直到我在程式碼中找到一個函式,該函式包含一個數組作為參數的預設值 - 這就是貪婪的正則表達式讓我絆倒的地方:

echo 'function foo(bar=array())' | sed 's:\(function.*(\)\(.*\):\1\n\t\2:g'

這實際上給出了:

function foo(bar=array(
   ))

貪婪導致在最後一個 (而不是第一個之後添加換行符和製表符。不幸sed的是不支持貪婪的正則表達式,它會立即解決所有問題……

因此,我嘗試製作一個可以執行以下操作的正則表達式,但我一無所獲:

  • 's:\(function [\w+]\)\(.*\):\1\n\2:g' 嘗試提取應該與第一個匹配的所有內容的字母數字(
  • 做同樣的嘗試使用一個:alnum:類來匹配這個詞
  • sed用更友好[A-Za-z0-9_-]但難以理解如何讓它匹配模式中的多個字元進行相同的替換,因此它將單詞帶到第一個(- 然後在第二個返回中獲取其餘的。

似乎這些字元類在查詢中被忽略了,我沒有想法。

由於我無法做到sed非貪婪,我如何匹配格式為

KnownKeyword SomethingRandomAlphaNumerical-_(SomethingElse())

變成一個字元串,在第一個 (, 之後的換行後看起來像:

KnownKeyword SomethingRandomAlphaNumerical-_(
SomethingElse())

我哪裡錯了?什麼模式可以做到這一點?

匹配以函式開頭的行,刪除第一個左括號,使用 GNU 添加新行和製表符sed

$ sed '/^function/s/(/&\n\t/' input_file
function foo(
   bar=array())

不要使用點.作為“任何字元”,使用否定字元匹配[^(]。因此,您的正則表達式將是:

$ echo 'function foo(bar=array())' | sed 's:\(function[^(]*(\)\(.*\):\1\n\t\2:g'

function foo(
   bar=array())

否定匹配將匹配除括號內的字元以外的任何字元^(和換行符除外)。這意味著 a[^(]可以理解為匹配“not (”。然後有一個*which 意味著盡可能多地重複,它仍然是貪婪的但不會匹配 a (。簡而言之:它將匹配每個字元直到下一個(。這種技術是.*通過給它一個限製字元來限制它的貪婪。

引用自:https://unix.stackexchange.com/questions/717570