在我的bash脚本中,我正在尝试执行以下Linux命令:
sed -i "/$data_line/ d" $data_dir
用户输入$data_line可能包含特殊字符,这些字符可能会破坏正则表达式。在执行sed命令之前,如何转义所有可能的特殊字符?
grep -v -F "$data_line" "$data_dir" > ...
您可以使用这种技术来保护选择器。下面标有"*****
"的行是重要的行。其他行大多用于测试和演示。关键是使用一个在用户输入中不出现的字符来分隔选择器地址。
data_line='.*/ s/GOLD/LEAD/g;b;/.*' # scary user input
candidates='/:.|@#%^&;,!~abcABC' # ***** # (make it as long as you like)
char=$(echo "$candidates" | tr -d "$data_line") # *****
char=${char:0:1} # ***** choose the first candidate that doesn't appear in the user input
if [ -z "$char" ] # ***** this test checks for exhaustion of the candidate character set
then
echo "Unusable user input. Recommendation: cigarette and blindfold."
exit 1
fi
# test without protection
excitement="GOLD, I tell you, thar's GOLD in them thar hills!"
echo "$excitement" | sed "/$data_line/ d"
# output: "LEAD, I tell you, thar's LEAD in them thar hills!"
# test WITH protection
echo "$excitement" | sed "\\${char}${data_line}${char} d" # *****
# output: "GOLD, I tell you, thar's GOLD in them thar hills!"
# test WITH protection and useful user input
data_line="secret"
mystery="The secret map is tucked in a hidden compartment in my saddle bag."
echo -e "$excitement\n$mystery" | sed "\\${char}${data_line}${char} d"
# output: "GOLD, I tell you, thar's GOLD in them thar hills!"
char=${candidates//[$data_line]}
代替使用echo
和tr
。 - Dennis Williamson这是一个老问题,但对于那些仍然来到这里的人来说,sed
允许您使用除正斜杠以外的分隔符。
对于我的脚本,我从 sed -i 's/$OLD_URL/$NEW_URL/g'
切换到了 sed -i 's|$OLD_URL|$NEW_URL|g'
,因为我的 URL 包含正斜杠,但不包含管道符。