cp和mv中的linux通配符使用

新手上路,请多包涵

我正在编写一个脚本来处理 20 个文件。它们都位于不同的目录中。我有部分文件名。

  1. 在日志目录中,File1_Date_time.err 更改为 File1__Date_time_orig.err
  2. cd ../脚本/
  3. sh 文件.sh

File1 目录为 /data/data1directory/Sample_File1/logs/File1_Data_time.err

File2 目录为 /data/data2directory/Sample_File2/logs/File2_Data_time.err

……

我的脚本看起来像这样。 (runrunrun.sh)

 #!/bin/bash
INPUT=$1
mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
sh /data/*/Sample_*/scripts/*_orig.sh

运行它时,我尝试过。

./runrunrun.sh 文件1

. runrunrun.sh 文件 1

sh runrunrun.sh 文件 1

mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No such file or directory cp也得到了类似的反馈

我做对了吗?

谢谢!

原文由 TJ Wu 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 841
2 个回答

让我们讨论一下通配符是如何工作的。

 cp *.txt foo

如果存在与该 glob 匹配的任何文件,则实际上不会使用参数 *.txt 调用 cp 。相反,它运行如下:

 cp a.txt b.txt c.txt foo

同样,类似

mv *.txt *.old

…不可能知道该怎么做,因为当它被调用时,它看到的是:

 mv a.txt b.txt c.txt *.old

或者,更糟糕的是,如果您已经 一个名为 z.old 的文件,它会看到:

 mv a.txt b.txt c.txt z.old


因此,您需要使用不同的工具。考虑:

 # REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
  mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done

# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
  cp "$f" "${f%.sh}_orig.sh"
done

# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
  if [[ -e "$f" ]]; then
    # honor the script's shebang and let it choose an interpreter to use
    "$f"
  else
    # script is not executable, assume POSIX sh (not bash, ksh, etc)
    sh "$f"
  fi
done

这使用 参数扩展 在添加新名称之前去除旧名称的尾部。

原文由 Charles Duffy 发布,翻译遵循 CC BY-SA 3.0 许可协议

find 命令可以非常简洁地用于您想要对通配符(或更复杂的)文件名匹配执行操作的简单情况。下面的技术可以致力于记忆……几乎!

这通过让 find 命令在它找到的每个文件名上运行另一个命令来工作。您可以使用 echo 代替/在 mv 之前空运行此示例。

如果我们想将当前目录中名称以“report”开头的所有文件移动到另一个名为“reports”的并行目录:

 find . -name "report*.*" -exec mv '{}' ../reports/ \;

通配符字符串必须用引号括起来,标记“找到”的文件名的 {} 必须用引号括起来,最后的分号必须被转义——所有这些都是由于 Bash/shell 对这些字符的处理。

查看 find 的手册页以了解更多用途: https ://linux.die.net/man/1/find

原文由 MikeW 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题