Bash脚本将某种类型的文件复制到另一个位置

时间:2014-01-14 06:40:43

标签: macos bash shell

我在想是否可以使用BASH脚本而无需手动复制此父目录中的每个文件

 "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk
/System/Library/PrivateFrameworks"

因此,在此文件夹PrivateFrameworks中,有许多子文件夹,并且在每个子文件夹中,它包含我要将其复制到另一个位置的文件。所以路径的结构如下所示:

-PrivateFrameworks  
     -AccessibilityUI.framework 
        -AccessibilityUI <- copy this
     -AccountSettings.framework
        -AccountSettings <- copy this  

我不希望复制文件夹中的整个内容,因为可能存在文件夹包含我不想复制的文件的情况。所以我想到的唯一方法是通过文件扩展名进行复制。但是正如您所看到的,我指定用于复制的文件没有扩展名(我认为?)。我是bash脚本的新手,所以我不熟悉是否可以用它来完成。

2 个答案:

答案 0 :(得分:2)

要复制当前目录中或下面没有扩展名的所有文件,请使用:

find . ! -name '*.*' -exec cp -t /your/destination/dir/ {} +

find .命令查找当前目录中或下面的所有文件。参数-name '*.*'会将搜索限制为具有扩展名的文件。然而,通过在其前面加上not(!),我们得到 not 的所有文件都有扩展名。然后,-exec cp -t /your/destination/dir/ {} +告诉find将这些文件复制到目的地。

要在您的目录中使用长名称执行上述操作,请使用:

find "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/PrivateFrameworks" ! -name '*.*' -exec cp -t /your/destination/dir/ {} +

更新:此问题上的unix标记已被删除,并替换为OSX标记。这意味着我们无法在-t上使用cp选项。解决方法是:

find . ! -name '*.*' -exec cp {} /your/destination/dir/ \;

效率较低,因为为每个移动的文件创建了一个新的cp进程,而不是为适合命令行的所有文件创建了一个进程。但是,它将完成同样的事情。

更多信息: -exec命令的find子句有两种变体。在上面的第一次使用中,子句以{} +结束,告诉find用尽可能多的文件名填充命令行的末尾。

但是,由于OSX缺少cp -t,我们必须将文件名放在命令的中间。因此,我们将{}放在我们想要文件名的位置,然后向find发出exec命令结尾的信号,我们添加一个分号。但是有一个技巧。因为bash通常会使用分号而不是传递给find,所以我们必须用反斜杠来转义分号。这样bash就可以将它发送给find命令。

答案 1 :(得分:0)

sh SCRIPT.sh copy-from-directory .extension copy-to-directory

FROM_DIR=$1
EXTENSION=$2
TO_DIR=$3

USAGE="""Usage: sh SCRIPT.sh copy-from-directory .extension copy-to-directory

- EXAMPLE: sh SCRIPT.sh PrivateFrameworks .framework .
- NOTE: 'copy-to-directory' argument is optional
"""

## print usage if less than 2 args
if [[ $# < 2 ]]; then echo "${USAGE}" && exit 1 ; fi

## set copy-to-dir default args
if [[ -z "$TO_DIR" ]] ; then TO_DIR=$PWD ; fi

## DO SOMETHING...
## find directories; find target file; 
## copy target file to copy-to-dir if file exist
find $FROM_DIR -type d | while read DIR ; do
    FILE_TO_COPY=$(echo $DIR | xargs basename | sed "s/$EXTENSION//")

    if [[ -f $DIR/$FILE_TO_COPY ]] ; then
        cp $DIR/$FILE_TO_COPY $TO_DIR
    fi
done