【问题标题】:Pass a regular expression as a parameter to a shell script将正则表达式作为参数传递给 shell 脚本
【发布时间】:2012-08-11 01:41:32
【问题描述】:

如何将正则表达式作为参数传递给 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

【问题讨论】:

  • 你说'我需要写一个shell,它将......';你是说shell还是shell脚本?编写 shell 的复杂性远大于编写 shell 脚本。当您说“正则表达式”时,您的意思是“shell glob 表达式”吗? '编写脚本等效于cp 命令,仅使用此命令'是什么意思?只使用cp,还是只使用shell脚本而不使用cp?或者...

标签: regex bash shell parameters


【解决方案1】:

修改后的问题

我正在尝试创建一个文件“mycp”

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

并调用它

mycp myDir "*sh" 

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

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

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

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

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


原问题

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

eval cp "$@"

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


很长一段时间(比如 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

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

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

【讨论】:

  • 这只是一个例子。假设我需要向后做: mycp arg1 arg2 相当于 cp arg2 arg1
【解决方案2】:

试试这个:eval cp $1 $2

Bash reference manual: eval

【讨论】:

  • 好吧 eval 给出相同的结果 + eval cp '*sh' aa ++ cp '*sh' aa cp: *sh: No such file or directory
  • 对我来说很好。请提供额外信息:至少ls 在您的工作目录中列出
  • #!/bin/bash -fx”中的“f”正在发挥作用。它抑制通配符扩展,所以它适用于你,Nya,但不适用于@klm123。
【解决方案3】:

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

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

否则:

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

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

(注意,*.sh 不是正则表达式,它是shell "pattern",通常称为“glob 模式”)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 2013-03-28
    • 2014-08-12
    • 1970-01-01
    • 2015-10-12
    相关资源
    最近更新 更多