2010-09-16 194 views
0

我想在shell脚本shell脚本问题

cp /somedire/*.(txt|xml|xsd) /destination/dir/

执行下面的命令,但这并不shell脚本内运行。任何快速帮助?

createjob.sh:第11行:附近意外的标记语法错误'(”

我的壳是zsh的

感谢 Nayn

+0

该脚本是否也由zsh执行? – ngroot 2010-09-16 19:13:50

+0

该命令在zsh中执行得很好。但是在shell脚本里面它只有一个婴儿床 – Nayn 2010-09-16 19:15:53

回答

2

您使用括号和替换是zsh特定的构造。它在其他shell中不起作用,包括sh sh兼容模式下的zsh。

如果你想继续使用这个构造,你必须调用zsh作为zsh(大概是用#!/bin/sh代替#!/bin/zsh或类似的东西)。

如果您需要脚本在ksh的运行,使用#!/bin/ksh#!/usr/bin/env ksh

cp /somedire/*[email protected](txt|xml|xsd) /destination/dir/ 

如果您还需要支持的bash,用@同样的命令将工作只要你第一次运行以下命令:

shopt -s extglob 2>/dev/null ## tell bash to parse ksh globbing extensions 
setopt ksh_glob 2>/dev/null ## tell zsh to parse ksh globbing extensions 

如果您需要POSIX兼容的sh,你将不得不使用三个独立的命令,和一个错误信息准备,如果任何的三个分机没有比赛。一个更强大的解决方案将使用发现:

find /somedire -name /somedire -o -type d -prune -o \ 
    \(-name '*.txt' -o -name '*.xml' -o '*.xsd' \) \ 
    -exec sh -c 'cp "[email protected]" "$0"' /destination/dir {} + 
0

有关的zsh不知道,但击不知道。正则表达式中的路径,只有通配符

您可以尝试使用find

find -E . -regex '.*\.(txt|xml|xsd)' -exec cp {} /destination/dir \; 

查看关于find的语法解释的联机帮助页。

+0

'*。(txt | xml | xsd)'是zsh中的一个shell模式,它意味着你的想法。请注意,'-E'不是标准的(它似乎特定于FreeBSD)。你的命令与原来的不同之处在于它递归到子目录中。 – Gilles 2010-09-16 20:04:01

+0

@Gilles:'-E'确实是非标准的,但如果没有它,使用Unix命令('sed','grep' ...)是* ss中的一个真正的痛苦,因为你得到的只是上一个千年的正则表达式版本。 – 2010-09-17 07:23:43

0

这将在bash工作,可能的zsh还有:cp /somedire/*.{txt,xml,xsd} /destination/dir/

这不是在POSIX,虽然如此,它不会与大多数/bin/sh的工作。

+0

当且仅当存在和txt,xml和xsd文件时,它才会起作用,而'(|)'版本只有在没有带有这种扩展名的文件时才会失败。 – ZyX 2010-09-16 20:57:20

+0

所以,如果有_are_文件,其他工作,如果没有文件,其他失败......我不明白你指出的差异。 – 2010-09-17 06:21:53

+0

如果存在例如* .txt和* .xml文件,但没有* .xsd文件,则您的命令应该失败。取决于shell选项,它可能会离开'/ somedire/*。xsd'模式(如bash),没有任何东西(在这种情况下,它的作用类似于'(|)'版本)(使用'nullglob'选项),或者拒绝运行带'no matches found'错误的命令(默认为zsh)。 – ZyX 2010-09-20 20:51:54