我想将除名为 *.data 的数据文件之外的所有文件和子目录复制到目标目录。
[ichen@ui01 sub_test]$ ls
a.cxx a.data subdir
[ichen@ui01 sub_test]$ ls subdir/
sub_a.cxx sub_a.data
您可以看到,外部目录和子目录中分别有 2 个数据文件。我使用了这个命令:
[ichen@ui01 sub_test]$ cp -r !(*.data) ../destination_dir/
旨在将除 *.data 之外的所有文件复制到目标,但在子目录中不起作用:
[ichen@ui01 destination_dir]$ ls
a.cxx subdir
[ichen@ui01 destination_dir]$ ls subdir/
sub_a.cxx sub_a.data
您可以在上面看到该命令只对第一个目录有效,我怎样才能让它在所有子目录中有效?
答案1
你的问题中没有说明是否需要在副本中保留目录结构,或者是否只需要文件的副本。要简单地复制所有未命名为 *.data 的文件,你可以使用以下命令:
find . -type f ! -name '*.data' | xargs cp -t ../destination_dir/
另一方面,如果您想保留目录结构,您可以使用如下方法:
for file in `find . ! -name '*.txt' | sed 's/^.\///'`; do if [ -d "./$file" ]; then mkdir -p "../destination_dir/$file"; else cp "./$file" "../destination_dir/$file"; fi; done
不确定是否有更简单的方法来做到这一点,但此命令执行以下操作:
查找当前目录中或其子文件夹中与 *.data 不匹配的所有文件和文件夹,然后对每个文件和文件夹执行以下任一操作:
如果文件是目录,则测试该文件是否为目录,如果是,则在目标目录下创建匹配的目录;如果文件是文件,则将其复制到目标。
编辑:添加 shell 脚本版本:
#!/bin/bash
# Disable shell glob expansion within the script
# Required to stop bash from expndinging the glob in $1
set -f
for file in `find . ! -name $1 | sed 's/^.\///'`
do if [ -d "./$file" ]; then
mkdir -p "$2/$file"
else
cp "./$file" "$2/$file"
fi
done