繁体   English   中英

在shell脚本中有没有分隔符的接受特殊字符的方法吗?

[英]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 noglobset -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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM