1

如何将正则表达式作为参数传递给 shell 脚本?

我需要编写一个 shell 脚本,它将接受参数并将它们提供给 unix 命令。我想在那里使用正则表达式。这可能吗?

或者重新制定 - 如何编写相当于“cp”命令的脚本,只使用这个命令?

我正在尝试制作一个文件“mycp”

#!/bin/bash -fx
cp $2 $1 

并通过调用它

mycp myDir "*sh" 

并希望它与“cp *sh myDir”做同样的事情。但由此产生的 bash 解释是:

+ cp '*sh' myDir
cp: *sh: No such file or directory
4

3 回答 3

2

修改后的问题

我正在尝试制作一个文件“mycp”

#!/bin/bash -fx
cp $2 $1 

并通过调用它

mycp myDir "*sh" 

在这种情况下,你仍然需要eval,但你会写:

#!/bin/bash -x
eval cp "$2" "$1"

您遇到了问题,因为您已经指定了-f选项。 man bash说(部分):

分词后,除非-f已设置该选项,否则 bash 会扫描每个单词中的字符*?[.

f从脚本的“shebang”(第一)行中删除。


原始问题

鉴于您想mycp "*sh*" aa对参数进行 shell 扩展,您可能最终会eval在脚本中使用:

eval cp "$@"

但是,使用eval是危险的;它可能会导致意想不到的副作用。使用"$@"很重要;它保留了参数和空格的数量。不幸的是,使用evalthen 取消了这一点,但我们不能拥有一切——或者不容易。


很长一段时间(比如 1987 *到 1999 年),我用这个脚本作为封面cp

:   "@(#)$Id: cp.sh,v 1.3 1997/06/02 21:45:00 johnl Exp $"
#
#   Alternative copy command

case $# in
0)  /bin/cp     ;;
1)  /bin/cp $1 .    ;;
2)  /bin/cp "$@"    ;;
*)  if [ -d `la "$@"` ]
    then    /bin/cp "$@"
    else    /bin/cp "$@" .
    fi;;
esac

它使用一个非常简单的 C 程序la(用于“最后一个参数”)来获取最后一个参数并检查给定的最后一个参数是否是一个目录。超过 99% 的时间,如果我(偶然)输入 'cp /some/where/ sh ' 而不是 ' cp /some/where/*sh* .,第二个就是我的意思,并且脚本修复了问题。我已经有一段时间没有使用它了;它可能是在上个千年,但可能是在这之前的某个时候,我放弃了使用它。

* 虽然版本字符串显示“1997”,但代码与 1987 版本相同。版本 1.1 和 1.2 在 SCCS 下,使用不同的 SCCS ID 字符串;转换为 RCS 使它们完全相同。版本 1.3 将@(#)SCCSwhat命令使用的标识符字符串恢复到 RCS 版本处理。所以,剧本很古老——真的是 1987 年。

于 2012-08-11T01:57:21.130 回答
1

试试这个:eval cp $1 $2

Bash 参考手册:eval

于 2012-08-11T01:46:50.800 回答
1

如果您只想先指定目录,请查看-tGNU cp 的选项:

alias mycp='cp -t'
mycp mydir *.sh

除此以外:

mycp() {
  local dir=$1
  shift
  cp "$@" "$dir"
}
mycp mydir *.sh

无论哪种方式,让 shell 扩展通配符并避免使用eval

(注意,*.sh不是正则表达式,它是一个外壳“模式”,通常称为“glob 模式”)

于 2012-08-11T03:24:58.040 回答