[英]Any way to accept special characters without delimiters in a shell script?
我的任务是制作一个交换2个字符串然后输出文件的shell脚本。 命令类似于:
sed s / search_for / 替换 / g output.txt> temp.dat
mv temp.dat output.txt
该脚本的工作方式如下:
./myScript var_A var_B output.file
我必须工作正常。 第二部分做同样的事情,但是我必须将以下特殊字符视为常规字符串:
[ ] ^ * + . $ \ -
我对如何解决这个问题有一个大致的了解(这可能是错误的方式)。 我想接受这些字符并将它们设置为变量,并在前面附加\\。
var_A=\\$1
var_B=\\$2
我的问题是*(星号)和\\(反斜杠)字符。 我使用一个简单的测试脚本来查看可以轻松将哪些参数转换为变量:
for i in "$@"
do
echo "$i"
done
但是* char显示目录中的所有文件,\\显示下一个参数。 我知道set -o noglob和set -f ,但是它们对我不起作用(并且在脚本上不起作用)。 我也知道您可以使用反斜杠进行转义,但我也不能使用。 我必须能够使用特殊字符(甚至*和/)并将其转换为字符串。 我希望这一切都有意义,有人可以帮助我。
如果我理解正确,可以将模式放入变量中,然后在sed
使用这些变量,并且需要将这些模式视为文字字符串,而在正则表达式中没有特殊含义?
如果是这样,那么在将模式传递给sed
,您需要转义特殊符号。 这是我的测试可能的实现:
#!/bin/sh
escaped() {
echo "$1" | sed -e 's/[].+-[$\\^*]/\\&/g'
}
set -- [ ] ^ \* + . \$ \\ -
for pat1; do
pat2=$(escaped "$pat1")
echo "$pat1 was $pat1" | sed -e s/$pat2/_/
done
escaped
函数接受参数,并在特殊字符前面加上反斜杠。 循环演示了以这种方式生成的pat2
变量正确匹配输入字符串中的特殊字符。
如果要执行文字替换,则sed
是执行此任务的错误工具。
请参阅http://mywiki.wooledge.org/BashFAQ/021中提供的awk脚本。 在这里引用:
# usage: gsub_literal STR REP
# replaces all instances of STR with REP. reads from stdin and writes to stdout.
gsub_literal() {
[[ $1 ]] || return
awk -v str="${1//\\/\\\\}" -v rep="${2//\\/\\\\}" '
BEGIN { len = length(str); }
{
out = "";
while (i = index($0, str)) {
out = out substr($0, 1, i-1) rep;
$0 = substr($0, i + len);
}
out = out $0;
print out;
}
'
}
...可以用作...
tempfile=$(mktemp "$file.XXXXXX")
gsub_literal "$search" "$rep" \
<"$file" \
>"$tempfile" && \
mv -- "$tempfile" "$file"
绝对包含$search
和$rep
任何值。
Perl也非常适合这种类型的操作,具有内联替换功能,并且(与sed不同)具有直接引用其argv数组或环境变量以进行文字搜索或替换值的能力。
您必须在Shell的命令行上引用模式。 您无法解决该问题。
Perl正则表达式为您提供了一个“ quotemeta”函数,该函数将每个字符视为文字
perl -e '
$str = q{this is a string with **emphasis**};
$pattern = q{**emphasis**};
$repl = "characters";
$str =~ s/$pattern/$repl/;
print $str
'
Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE *emphasis**/ at -e line 5.
但
perl -e '
$str = q{this is a string with **emphasis**};
$pattern = q{**emphasis**};
$repl = "characters";
$str =~ s/\Q$pattern\E/$repl/;
#.........^^
print $str
'
this is a string with characters
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.