如何從遞歸檔案複製中排除特定副檔名?

如何從遞歸檔案複製中排除特定副檔名?

我想將除名為 *.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

相關內容