San*_*ing 1 linux bash perl sed
如果我做
comment () { sed -i "/$1/s/^/$2 /g" $3 }
comment /dev/sysmsg '#' /tmp/1
comment '*.err' '#' /tmp/1
Run Code Online (Sandbox Code Playgroud)
带输入文件
*.err;kern.notice;auth.notice /dev/sysmsg
fff
ff
Run Code Online (Sandbox Code Playgroud)
然后它就像/在sed分隔符中那样断开,*也被视为正则表达式.
题
有没有办法使它健壮,所以输入字符串$1可以包含我想要的任何东西?或者我需要转移到Perl?
当然,使用bash参数替换来逃避麻烦的斜线字符:
comment () { sed -i "/${1//\//\\/}/ s/^/${2//\//\\/} /" "$3"; }
Run Code Online (Sandbox Code Playgroud)
笔记:
演示
$ cat file
test/1/
test/2/
test/3/
$ comment 'test/2' '//' file
$ cat file
test/1/
// test/2/
test/3/
Run Code Online (Sandbox Code Playgroud)
我意识到我并没有逃避正则表达式的特殊字符.最安全的方法是转义任何非字母数字字符:
comment () {
local pattern=$(sed 's/[^[:alnum:]]/\\&/g' <<<"$1")
local replace=${2//\//\\/}
local file=$3
sed -i "/$pattern/ s/^/$replace /" "$file"
}
Run Code Online (Sandbox Code Playgroud)
但既然你想做纯文本匹配,sed可能不是最好的工具:
comment() {
perl -i -pse '$_ = "$leader $_" if index($_, $search) > -1' -- \
-search="$1" \
-leader="$2" \
"$3"
}
Run Code Online (Sandbox Code Playgroud)