有人可以向我解释一下我使用的查找命令行为吗?

有人可以向我解释一下我使用的查找命令行为吗?

有人能告诉我为什么以下命令无法运行:

find ./assign/*.c -exec cp ./assign2 {} \;

当我执行以下操作时(实际运行)有什么区别:

find ./assign -type f -name *.c  -exec cp {} ./assign2 \;

答案1

find ./assign/*.c -exec cp ./assign2 {} \;

shell 在执行 find 之前就已经扩展了通配符 ( *)。假设在assign 目录中有两个文件 source1.c 和 source2.c,那么上面的代码相当于

find ./assign/source1.c ./assign/source2.c -exec cp ./assign2 {} \;

这当然是有效的,并且意味着你只想对这些特定文件执行某些操作。例如,你可以写

find ./assign/*.c -name '*2*'

结果大致相当于ls ./assign/*.c | grep 2ls ./assign/*2*.c

请注意,如果您不想让 shell 扩展通配符,则需要将它们放在引号中:

find "./assign/*.c"

但是,这样做会失败,因为 find 按字面意思来处理路径名(没有任何通配符扩展),所以它看起来字面上地对于名为*.c(是的,这是一个有效的文件名)。

至于第一个表达式的第二部分(exec cp ./assign2 {} \;)。显然,这是一个拼写错误,因为 cp 命令试图将assign2 目录复制到第二个参数。假设您在assign 目录中有文件source1.c 和source2.c,则命令的结果将等同于

cp assign2/ ./assign/source1.c
cp assign2/ ./assign/source2.c

这可能不是您想要的(而且它会失败,因为您无法将目录复制到文件名)。

现在,对于第二个表达式,因为这里也有一个问题:

find ./assign -type f -name *.c  -exec cp {} ./assign2 \;

这将有效仅有的.c如果当前目录中没有带扩展名的文件。否则,shell 将扩展*.c。假设您有以下文件:

./master.c
./assign/source1.c
./assign/source2.c

上述命令行将首先被 shell 扩展为

find ./assign -type f -name master.c -exec cp {} ./assign2 \;

这将失败,因为在assign/目录中没有文件master.c。相反,使用

find ./assign -type f -name "*.c" -exec cp {} ./assign2 \;

无论如何,除非你在 ./assign 下有一个复杂的目录结构或以 结尾的目录.c,否则我宁愿只

cp ./assign/*.c ./assign2

答案2

对于“查找”,您需要按顺序指定:

  • 在哪里搜索(./assign)
  • 文档类型(-type f 又称文件),但这是可选的
  • 文档名称(-name *.c,即每个扩展名为 .c 的文件),这不是可选的

然后,您告诉“find”,在搜索之后,它必须运行特定的命令(-exec),并且您发出的两个命令中“cp”的语法都是正确的,但由于第一个命令中“find”的语法不正确,所以第一个命令将不会运行。

顺便说一句,我认为在找到所有 .c 文件后,将目录 ./assign2 复制到实际查找 ({}) 没有任何意义,而应该反过来。也就是说,在我看来,即使语法正确,第一行中的“cp”命令也不会执行任何操作。

相关内容