我正在使用sed
更新運行時的json配置文件。 有時,當模式不以JSON文件sed
退出,返回代碼匹配,仍爲0sed的返回碼不匹配
返回0表示成功完成,但爲什麼sed
返回0,如果它不找到合適的模式和更新文件?有沒有解決方法?
謝謝!
我正在使用sed
更新運行時的json配置文件。 有時,當模式不以JSON文件sed
退出,返回代碼匹配,仍爲0sed的返回碼不匹配
返回0表示成功完成,但爲什麼sed
返回0,如果它不找到合適的模式和更新文件?有沒有解決方法?
謝謝!
as @cnicutar評論說,命令的返回碼意味着命令是否成功執行。與您在代碼/腳本中實施的邏輯無關。
,如果您有:
echo "foo"|sed '/bar/ s/a/b/'
的sed將返回0
但如果你寫一些語法/表達錯誤,或者輸入/文件不存在,sed中不能執行您的要求,用sed將返回1 。
解決方法
這其實不是解決辦法。 SED具有q
命令:(從手冊頁):
q [exit-code]
在這裏你可以定義退出代碼,只要你想。例如:
匹配情況:
kent$ echo "foo"|sed '/foo/ {s/f/b/;q}'
boo
kent$ echo $?
0
無可比擬的情況:
kent$ echo "trash"|sed '/foo/{s/f/b/;q}; /foo/!{q100}'
trash
kent$ echo $?
100
我希望這回答了你的問題。
編輯
我必須補充的是,上面的例子是隻在一個行的處理。我不知道你的具體要求。當你想得到exit 1
。一行不匹配或整個文件。如果search-string
發現它
sed '/search-string/{s//replacement-string/;h};${x;/./{x;q0};x;q1}' file
:如果整個文件不匹配的情況下,你可能會考慮AWK,甚至做你的文字處理之前grep
...
這可能會爲你工作(GNU SED)將被替換爲replacement-string
,並且在文件結尾sed
將以0
返回代碼退出。如果沒有替換髮生,返回碼將是1
。
更詳細的解釋:
在sed用戶具有在他的處置兩個寄存器:模式空間(PS),其中電流線被加載到(減去換行)和備用寄存器稱爲保持空間(HS)最初是空的。
總的想法是使用HS作爲標誌來指示是否發生了替換。如果文件末尾的HS仍爲空,則不會進行更改,否則會發生更改。
命令/search-string/
匹配search-string
與無論是在PS和如果它被發現含有以下大括號之間的search-string
的命令被執行。
首先取代s//replacement-string/
(SED使用最後的regexp即search-string
,如果左手側是空的,所以s//replacement-string
相同s/search-string/replacement-string/
)並按照這個h
命令使PS的副本,並把它放在HS。
sed命令$
用於識別文件的最後一行,然後出現以下內容。
首先,x
命令交換兩個寄存器,所以HS成爲PS,PS成爲HS。
然後在PS中搜索任何字符/./
(.
表示匹配任何字符)記住HS(現在的PS)最初是空的,直到發生替換。如果條件爲真,則再次執行x
,然後執行q0
命令,該命令結束所有sed處理並將返回碼設置爲0
。否則,執行x
命令並將返回碼設置爲1
。
N.B.儘管q
退出了sed處理,但它並不妨礙通過sed重新組裝se並按正常方式打印。
另一種選擇:
sed '/search-string/!ba;s//replacement-string/;h;:a;$!b;p;x;/./Q;Q1' file
或:
sed '/search-string/,${s//replacement-string/;b};$q1' file
我本來想通過比賽時被發現戒菸截斷文件(並排除匹配的行)。當在文件末尾添加行的進程可能會重新運行時,這很方便。 「Q; Q1」不起作用,但只是「Q1」,如下所示:
如果sed -i'/ text我想查找/ Q1'file.txt 然後 在文件結尾插入空白行+新行 fi 只插入沒有空行的新行
下面是我們與sed -rn
或sed -r
使用該模式。
整個搜索和替換命令(「s/.../.../...」)是可選的。如果使用搜索和替換,爲了速度並且已經匹配$ matchRe,我們使用盡可能快的$ searchRe值。字符不需要重新驗證,並且。{$ len}用於模式的固定長度部分。
找不到的返回值是$ notFoundExit。
/$matchRe/{s/$searchRe/$replacement/$options; Q}; q$notFoundExit
原因有以下幾點:
改變Q命令的情況會根據退出何時發生而改變行爲。涉及將布爾邏輯應用於多行輸入的行爲在解決方案中需要更多的複雜性。
正如我們已經知道的那樣,當sed不匹配時,它只是返回它的輸入字符串 - 沒有發生錯誤。確實,輸入和輸出字符串之間的差異意味着匹配,但匹配並不意味着字符串的差異;畢竟sed可以簡單地匹配所有的輸入字符。 該缺陷將在下面的示例中創建
h=$(echo "$g" | sed 's/.*\(abc[[:digit:]]\).*/\1/g')
if [ ! "$h" = "$g" ]; then
echo "1"
else
echo "2"
fi
其中g=Xabc1
得到1,同時設定g=abc1
給出2;然而這兩個輸入字符串都是由sed匹配的!因此,很難確定sed是否匹配。 A液:
h=$(echo "fix${g}ed" | sed 's/.*\(abc[[:digit:]]\).*/\1/g')
if [ ! "$h" = "fix${g}ed" ]; then
echo "1"
else
echo "2"
fi
1打印如果且僅-如果sed的已匹配。
是的,就'sed'而言,它做了它的工作:它試圖編輯文件。如果文件不可讀或類似的話,它會返回一個錯誤代碼。總之,我不認爲'sed'是決定*文件中是否出現模式*的最佳工具。 – cnicutar
@cnicutar很多人發表評論作爲答案,但我認爲你只是在評論區放回答。我猜OP不僅希望檢查模式匹配,他希望做一些事情,如果模式匹配..像'/ pat/s/foo/bar/...' – Kent
@Kent這就是爲什麼我沒有發佈一個回答。我解釋了爲什麼'sed'這樣做,但無法提出一個可接受的解決方案。我想到的所有事情都需要在'sed'之前調用一個單獨的命令,以便確定文件是否匹配。理想情況下,應該有一些解決方案(可能'awk'和'gsub'?),可以在一個命令中完成。 – cnicutar