2

我正在尝试运行以下脚本并将具有特定名称模式的文件从源复制到工作。

#!/bin/bash
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required
SOURCE="D:/backup/"
WORKING="D:/copyFromHere/"
Copy_Pattern="P0689\|P1391\|P0730"

for FILE in $(find "$SOURCE" `ls -Rl "$SOURCE" | egrep '^d' | awk '{print $9}'` -print 
2>/dev/null | grep "$COPY_PATTERN" |sed 's/_[0-9]\+//' | uniq);

do
cp -f "FILE" "$WORKING";

done;

我在 Windows 上的 cygwin 上运行它。

但我得到以下错误 cp cannot stat file no such file or directory

请帮我解决这个问题。

谢谢,汤姆

4

3 回答 3

1

"FILE"只是一个字符串。您正在尝试复制名称为FILE. 也许你的意思是

cp -f "$FILE" "$WORKING";
       ^--- missing $?
于 2013-07-08T19:55:11.470 回答
0

我可以提出一个小小的建议:

#!/bin/bash
set -xv
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required
SOURCE="D:/backup/"
WORKING="D:/copyFromHere/"
Copy_Pattern="P0689\|P1391\|P0730"

for FILE in $(find "$SOURCE" `ls -Rl "$SOURCE" | egrep '^d' | awk '{print $9}'` -print 2>/dev/null | grep "$COPY_PATTERN" |sed 's/_[0-9]\+//' | uniq);
do
    echo "cp -f \"FILE\" \"$WORKING\"";
done;
set +xv

set -xv是一个shell的调试器。它打印出您在 shell 脚本中所写的正在执行的行,然后在所有变量插值完成后打印出该行。这将让您看到您的程序正在执行的每一组,以及它可能出现问题的地方。set +xv只是关闭调试。

我怀疑问题是存在的,cp -f "FILE" "$WORKING"因为该文件FILE实际上并不存在。我还怀疑您正在获取文件名(并且在那里复制失败),并且在将文件复制到那里之前您可能没有检查目录是否确实存在。使用set -o xv,你会很清楚地看到很多这样的错误。

将您cp的语句放入echo语句中还可以让您在实际执行之前查看您计划执行的内容。这是帮助调试 shell 脚本的另一种方法。

我还怀疑你的for循环可能没有完全按照你的意愿做。这是一个过于复杂的坏男孩,您一次执行两个子 shell 命令。(一次使用和另一个使用反引号。由于各种问题,$(..)我强烈反对使用。首先,必须在循环开始之前完成执行- 没有并行操作。其次,如果有时髦的文件名称,您将简单地失败。第三,很有可能返回这么多文件,您的命令缓冲区溢出并静默删除文件名,甚至不让您知道它正在发生。您最好使用:for var in $(find ...)findforforfind

 find ... | while read something

它消除了您for将遇到的许多问题。

于 2013-07-08T21:03:36.280 回答
0

环境变量名称在 Cygwin 中区分大小写(与所有 POSIX shell 一样,与 Windows 不同),因此$Copy_Pattern(设置为P0689|P1391|P0730) 和$COPY_PATTERN(未定义) 是两个不同的变量。

您还应该知道-x命令行切换到 bash,它将在跟踪模式下运行您的脚本。这对于调试 bash 脚本非常有帮助,我相信它会帮助您找出问题所在。

于 2013-07-08T20:53:42.520 回答