我有一個包含很多文件的資料夾。我想複製以這些名稱開頭的所有檔案(用空格分隔):
abc abd aer ab-x ate
到另一個資料夾。我怎樣才能做到這一點?
答案1
與csh
, tcsh
, ksh93
, bash
,fish
或 一起zsh -o cshnullglob
,您可以使用大括號擴展和通配為此(--
這些文件名不需要,但我認為它們只是示例):
cp -- {abc,abd,aer,ab-x,ate}* dest/
如果您不想使用大括號擴展,則可以使用 for 迴圈(此處為 POSIX/Bourne 樣式語法):
for include in abc abd aer ab-x ate; do
cp -- "$include"* dest/
done
如果您有大量文件,則由於cp
每個包含調用一次,這可能會很慢。另一種方法是填入一個數組,然後從那裡開始(此處ksh93
或zsh
最近的bash
語法):
files=()
includes=(abc abd aer ab-x ate)
for include in "${includes[@]}"; do
files+=( "$include"* )
done
cp -- "${files[@]}" dest/
答案2
關於大括號擴充與通配符的註解。
大括號擴展不是通配符(儘管其區別在它起源的 csh/tcsh 中並不像在其他 shell 中那樣清晰)。它被執行前通配符。
所以,當你這樣做時:
cp {a,b}* /dest
首先將其擴展為:
cp a* b* /dest
這意味著 shell 必須擴展兩個 glob,即取得完整的檔案清單兩次,並查看哪些檔案與模式相符兩次。
對於zsh
,這也意味著如果任何 glob 與任何檔案都不匹配,則整個命令將被取消(您可以透過啟用該cshnullglob
選項以像 csh 中一樣運行來解決此問題)。
這也意味著如果你有
cp {a,ab}* /dest
cp
將複製ab*
文件兩次。
這與以下內容不同:
cp @(a|b)* /dest
或ksh
或bash -O extglob
或zsh -o kshglob
或
cp (a|b)* /dest
的zsh
。在那裡,只有一glob,這樣會更有效率,檔案只會被包含一次。
使用zsh
,如果您有數組中的前綴列表:
prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest
(上面,前綴被視為通配符)。即將數組的元素連接起來,|
並將結果視為 glob ( ~
)。
如果清單很大,您可能會發現執行cp
失敗並顯示“參數列表太長”錯誤。在這種情況下,您可以透過載入模組 ( ) 使用zsh
內建版本。cp
zsh/files
zmodload zsh/files
答案3
例如,我在目前目錄中有這些檔案:
1-s2.0-S0038092X0000058X-main.pdf ANNDHW.pdf HPcalculation2 1-s2.0-S0306261999000422-main.pdf ANNlee.pdf HPcalculation3 ANNCanada.pdf HPcalculation HPcalculation4
我想將從 HP 開始的所有檔案移至資料夾:
./NewFolder/
我可以:
cp ./HP* ./NewFolder/
./HP*
會告訴linux我對從HP開始的所有文件感興趣。相反,當我有興趣移動所有以.pdf
.我可以*
把.pdf
:cp ./*.pdf ./NewFolder/
答案4
簡單地你可以做
cp abc* abd* aer* ab-x* ate* DestinationPath
您的擴展問題的解決方案可以是
- 將所有檔案名稱放入清單中,例如list0.txt
全部複製與
cp `cat list0.txt` DestinationPath # 檔案名稱中不需要空格
或更好,
當讀取-r檔案時;執行 cp "$file" dest/ ;完成<list0.txt
筆記:
- “$file” 因為這樣你就可以處理有空格的名稱
One Package.deb
-r
它可以保護您免受轉義序列的影響。-r 反斜線不充當轉義字元。反斜線被認為是該行的一部分。特別是,反斜線-換行符對不能用作續行符