簡體   English   中英

如果在行中找到字符串,請用前一行sed的字符串替換

[英]If string is found in line, replace with string from previous line, sed

我有數千行代碼分布在需要更新的多個文件中。 現在他們就像這樣:

active_data(COPIED),

我需要將COCOPED的所有實例(僅在這些行中)替換為上一行中括號內的文本。 因此,總的來說,當前的代碼可能如下所示:

current_data(FOO|BAR|TEXT),
active_data(COPIED),

我希望它看起來像:

current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),

我可以很容易地找到要替換的行,可以用一些靜態字符串替換,這沒有問題,但是我不確定如何從前一行中提取數據並使用它。 我敢肯定它很簡單,但是還不太清楚。 謝謝您的幫助。

(如果sed不起作用,我也可以看到使用AWK或其他方法,但我認為sed是一次更改的最佳解決方案)。

sed可以工作,但是awk更自然:

$ awk -F'[()]' '$2 == "COPIED" {sub(/COPIED/, prev)} {prev=$2;} 1' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),
  • -F'[()]'

    使用開放式或寬松的括號作為字段分隔符。

  • $2 == "COPIED" {sub("COPIED", prev)}

    如果第二個字段已COPIED ,則將其替換為prev

  • prev=$2

    更新prev

  • 1

    這是個隱秘的縮寫,表示打印行。 等效於{print $0;}

awk如何看待領域

$ awk -F'[()]' '{for (i=1;i<=NF;i++)printf "Line %s Field %s=%s\n",NR,i,$i;}' file
Line 1 Field 1=current_data
Line 1 Field 2=FOO|BAR|TEXT
Line 1 Field 3=,
Line 2 Field 1=active_data
Line 2 Field 2=COPIED
Line 2 Field 3=,

就地更改目錄中的所有文件

for file in *
do
  awk -F'[()]' '$2 == "COPIED" {sub("COPIED", prev)} {prev=$2;} 1' "$file" >tmp$$ && mv tmp$$ "$file"
done

或者,如果您擁有現代的GNU awk:

awk -i inplace -F'[()]' '$2 == "COPIED" {sub("COPIED", prev)} {prev=$2;} 1' *

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

sed 'N;s/\((\([^)]*\)).*\n.*(\)COPIED/\1\2/;P;D' file

這將在整個文件的整個長度中保持2行移動窗口的打開,並使用模式匹配來實現所需的結果。

使用GNU awk for FPAT:

$ awk -v FPAT='[(][^)]*[)]|[^)(]*' -v OFS= '$2=="(COPIED)"{$2=prev} {prev=$2; print}' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),

與其他awk:

$ awk '
match($0,/\([^)]*\)/) {
    curr = substr($0,RSTART,RLENGTH)
    if (curr == "(COPIED)") {
        $0 = substr($0,1,RSTART-1) prev substr($0,RSTART+RLENGTH)
    }
    else {
        prev = curr
    }
}
{ print }
' file
current_data(FOO|BAR|TEXT),
active_data(FOO|BAR|TEXT),

暫無
暫無

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

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