2017-01-26 163 views
0
file=mylog.log 
search_str="&Name=" 
end_str="&" 
sed -i -E ':a; s/('"$search_str"'X*)[^X'"$end_str"']/\1X/; ta' "$file" 

Ex 1: 
something&Name=JASON&else 
to 
something&Name=XXXXX&else 

給定的兩個字符串之間而實際上,我現在的sed命令正常工作時,而不是X‘‘替換字符$ end_str’’如果我使用‘&’字。 ..就像這樣:bash腳本:在文件「「使用SED

sed -i -E ':a; s/('"$search_str"'X*)[^X&]/\1X/; ta' "$file" 

因此,要總結,認爲它,之後^ X,如果一個字符來比我給sed命令工作得很好......但是,如果不是性格相同的命令不起作用,我用一串...

For example, my sed command won't work in this case : 
end_str="\%26" 
sed -i -E ':a; s/('"$search_str"'X*)[^X'"$end_str"']/\1X/; ta' "$file" 

如:

something&Name=JASON_MATTHEW_DONALD%26else 
TO 
something&Name=XXXXXXXXXXXXXXXXXXXX%26else 

如:2

something&Name=JASON%26else 
TO 
something&Name=XXXXX%26else 

請讓我知道字符類的外部

+1

在'sed','[]'是一個字符類,而不是字符串。它表示'[]'中的任何單個字符。用'^'前綴,它表示任何不在'[]'中的單個字符。 – alvits

+0

@alvits謝謝Alvits ...所以,而不是[我應該使用什麼? –

+0

@PuneetJain:你能總結一下你的最終輸入和預期輸出嗎?目前尚不清楚。 – Inian

回答

0

將您的字符串變量,並捕獲它來檢查進一步的替換:

sed -i -E ':a; s/('"$search_str"'X*)[^X](.*'"$end_str"')/\1X\2/; ta' "$file" 
+0

不幸的是它沒有;噸worked.It替換&X和在之間吃許多字符。 ..可以微調一下上面的sed命令嗎? –

+0

嘗試逃避'&':'\&'。它是否與'\%26'一起使用? – SLePort

+0

我用\%26試過。沒有工作...單個字符&與我的orif = ginal sed命令一起工作,所以我不擔心它...但是使用\%26,我的和你的sed命令沒有工作......任何指針? –

0

如果X的數量無關緊要,可以將其簡化爲:

search="Name" 
sed "s/$search=[^&]*/$search=XXX/" input.file 

這假定$search將不包含已在sed's正則表達式語法的含義,特殊字符。如果特殊字符可能是一個問題,你需要準備的$search變量,如下解釋:Is it possible to escape regex metacharacters reliably with sed

+0

不幸的是X的數量很重要...... :: - ( –

+0

你能解釋一下爲什麼嗎? – hek2mgl

+0

因爲我需要用兩個字符串替換字符,數目相等X.見我編輯的問題示例1和2 –

0

我堅持,保持密碼的長度在日誌是一個非常糟糕的主意(安全方面)的點。

說了:

首先,一個字符列表[...]是不匹配的字符串的工具。爲此,我們需要使用交替值(...|...)

end_str="(&|%26)" 

但是在正則表達式中「非字符串」是相當困難的。

not_end_str="([^&]|[^%]|%[^2]|%2[^6])" 

利用所有我們可以建立一個純bash的解決方案(也許不是很快,但作品)。
它打印到標準輸出顯示它的工作原理。 重定向到一個文件來存儲結果。

file=mylog.log 
search_str="&Name=" 
end_str="(&|%26)"      # write end_str as an alternate value. 
not_end_str="([^&]|[^%]|%[^2]|%2[^6])" # regex negate end_string. 

# Build a regex that split each part of the text. 
myreg="(.*${search_str}X*)(${not_end_str}*)([&%].*)" 

while IFS=$'\n' read line; do 
    [[ $line =~ $myreg ]] 
    len=$((${#BASH_REMATCH[@]}-2))   # do not count [0] and last. 
    arr=("${BASH_REMATCH[@]:1}")   # remove [0] and last. 
    arr[1]=${arr[1]//?/X}     # Replace name with "X"'s. 
    arr[2]=''        # Clear not_end_str match 
    printf '%s' "${arr[@]}"; echo   # Print modified line. 
done <"$file" 

進一步閱讀: