[英]Replace value across multiple lines in bash
即使使用 stackoverflow 和 google 上可用的所有示例,我也在苦苦掙扎。
基本上我有以下文字
/start r.start ""
GAIN 0x256 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x256 0x2 10 0xA3
/end MACRO
OTHER
/end
我需要通讀這個文件,搜索作為 $1 傳遞的名稱 egrstart 並用我作為 $2 傳遞的值替換例如 0x256。 有兩個實例要替換,第 2 行和第 7 行。
我知道的事情:
直到現在我已經達到了這一點
pattern="N;s\s\/start r.start \"\"\n GAIN 0x\(.*\)"
replacement"\/start r.start \"\"\n GAIN 0x82"
sed -e "$pattern/$replacement/p" test.txt
但我一無所獲。 我也能夠替換第一行,但無論出於何種原因,它都將前兩行粘貼在彼此之上兩次
假設以下調用的預期值
./run.sh r.start 0x284569
應該
/start r.start ""
GAIN 0x284569 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x284569 0x2 10 0xA3
/end MACRO
OTHER
/end
這是我第二部分的最佳鏡頭
var="r.start"
val="0x48209F82"
pattern="\(CODE \"$var\" \).*\(.*\)"
replacement="\1$val\2"
sed "s/$pattern/$replacement/g" test.txt
問題是它在值替換后刪除了所有內容。 我不能輸入 \\2 以下字符
編輯:
通過執行以下操作
var="r.start"
val="0x48209F82"
pattern="\(CODE \"$var\" \).*\(\s.*\s.*\s.*\)"
replacement="\1$val\2"
sed "s/$pattern/$replacement/g" test.txt
我得到了我想要的東西,但感覺有點臟,如果字符數可變,我該如何減少最后一部分? 我可以以某種方式匹配所有內容直到行尾嗎?
像下面這樣的怎么樣? 它使用sed
范圍來選擇/start
和/end
之間的所有內容,並在該范圍內使用一個塊來替換與GAIN
和CODE
匹配的行的值。
$ cat foo.txt
/start r.start ""
GAIN 0x256 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x256 0x2 10 0xA3
/end MACRO
OTHER
/end
$ sed '\#/start r\.start#,\#/end#{/\(GAIN\|CODE "r\.start"\)/s/0x[a-fA-F0-9]\+/0x284569/}' foo.txt
/start r.start ""
GAIN 0x284569 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x284569 0x2 10 0xA3
/end MACRO
OTHER
/end
sed
腳本在格式良好時看起來像這樣:
\#/start r\.start#,\#/end# {
/\(GAIN\|CODE "r\.start"\)/s/0x[a-fA-F0-9]\+/0x284569/
}
筆記
\\#...#
而不是/.../
作為范圍模式,所以我們不必引用斜杠/patten1/s/pattern2/string/
替換pattern2
僅用於容納線pattern1
{...}
塊,以便替換僅適用於/start
和/end
您可以像這樣參數化模式和值:
#!/bin/bash
var='r\.start'
val='0x48209F82'
sed '\#/start '$var'#,\#/end#{/\(GAIN\|CODE "'$var'"\)/s/0x[0-9a-fA-F]\+/'$val'/}' foo.txt
這可能對你有用(GNU sed):
sed -E '/^ \/start r\.start /{:a;N;/^ \/end$/M!ba;s/^( GAIN | CODE "r\.start" )0x\S+/\10x284569/Mg}' file
收集/start
和/end
之間的行並使用模式匹配替換所需的值。
解決方案可以放在一個函數中:
f () { sed -E '/^ \/start '"$1"' /{:a;N;/^ \/end$/M!ba;s/^( GAIN | CODE "'"$1"'" )0x\S+/\1'"$2"'/Mg}' "$3"; }
並稱:
f r\\.start 0x284569 file
這是一個perl方式:
#!/usr/bin/perl
use strict;
use warnings;
# retrieve the 2 parameters
my $start = shift @ARGV or die "missing 1rst arg";
my $repl = shift @ARGV or die "missing 2nd arg";
# input file
open my $fh_in, '<', 'file.txt' or die "$!";
# output file
open my $fh_out, '>', 'output' or die "$!";
# loop through input file
while(<$fh_in>) {
# if we are between /start {1srt parameter} and /end
if (/^ {4}\/start\h+$start/ ... /^ {4}\/end\h*$/) {
# substitute 0x.... by {2nd parameter}
s/^(?: {6}GAIN | {8}CODE "$start" )\K0x\w+/$repl/;
}
print $fh_out $_;
}
在行動:
cat file.txt
/start other.start ""
GAIN 0x256 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x256 0x2 10 0xA3
/end MACRO
OTHER
/end
/start r.start ""
GAIN 0x256 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x256 0x2 10 0xA3
/end MACRO
OTHER
/end
./test.pl r.start 0x123456
cat output
/start other.start ""
GAIN 0x256 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x256 0x2 10 0xA3
/end MACRO
OTHER
/end
/start r.start ""
GAIN 0x123456 __POSITIVE 1 FOO
OTHER
OTHER
/start MACRO
200
CODE "r.start" 0x123456 0x2 10 0xA3
/end MACRO
OTHER
/end
您需要為此使用 sed,並且不需要腳本:
假設文本是一個名為 the_text 的文件:
sed "s/0x256/REPLACETEXT/g" the_text
如果你不想回顯文本就這樣做,然后添加 -i
sed -i "s/0x256/REPLACETEXT/g" the_text
可以菊花鏈這些命令或將它們嵌入到單個腳本中,這與標准輸出相呼應:
#!/bin/bash
sed "s/0x256/${2}/g" $1
sed "s/0x256/${2}/g" $1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.