2014-02-06 66 views
1

這裏是我的命令for循環和文件空間

for i in `find . -name '*Source*.dat'`; do cp "$i" $INBOUND/$RANDOM.dat; done; 

以下是文件(只是一個示例):

/(12)SA1 (Admitting Diagnosis) --_TA1-1 + TA1-2/Source.dat 
./(12)SA1 (Admitting Diagnosis) --_TA1-1 + TA1-2/Source_2000C.dat 
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source.dat 
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source_2000C.dat 
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source_POATest.dat 
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source.dat 
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source_2000C.dat 
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source_ProcDateTest.dat 
./(15)SP1(Primary)--_ TP1-1 + TP1-2 - SP2 -- TP2-1 + TP2-2/Source.dat 
./(16)SP1(Primary)--_ TP1-1 + TP1-2 +TP1-3- SP2 -- TP2-1 + TP2-2/Source.dat 
./(17)SP1(Primary)--_ TP1-1 + TP1-2 +TP1-3/Source.dat 
./(18)SP1(Primary)--_ TP1-1 + TP1-2 - SP2 -- TP2-1 + TP2-2 - Copy/Source.dat 
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source.dat 
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source_2000C.dat 
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source_POATest.dat 
./(2)SD3--_TD4 SD4--_TD4/Source.dat 
./(2)SD3--_TD4 SD4--_TD4/Source2.dat 

這些空間越來越受bash的符號化,這不工作。 此外,我想追加一些隨機到這些文件的結尾,所以它們不會在目標目錄中發生衝突,但這是另一回事。

+1

[shellcheck](http://www.shellcheck.net)指向循環並指出「使用find -exec或while循環讀取循環代替,因爲找到的循環會失敗,例如'我的文件*'等文件名。文本'。」它還[鏈接到一個頁面](https://github.com/koalaman/shellcheck/wiki/SC2044)與進一步的細節。 –

回答

3
find . -name '*Source*.dat' -exec sh -c 'cp "$1" "$2/$RANDOM.dat"' -- {} "$INBOUND" \; 

使用-exec要執行的命令是空白的安全。使用sh執行cp對於每個副本獲得不同的$RANDOM是必要的。

+0

這是神祕的地獄,但似乎工作:)我也會嘗試其他人 –

0

有幾種處理空間文件的方法。您可以在管道使用find,而讀:

find . -name '*Source*.dat' | while read file ; do cp "$file" "$INBOUND/$RANDOM.dat"; done 
1

如何:

find . -name '*file*' -print0 | xargs -0 -I {} cp {} $INBOUND/{}-$RANDOM.dat 

xargs是構建一個參數列表並將它傳遞給命令的一種方便的方法。

  • find -print0xargs -0走在一起,基本上都是關於如何終止參數的兩個命令之間的協議。在這種情況下,這意味着空間不會被解釋爲爭論的結束。

  • -I {}設置{}作爲參數佔位符xargs

至於隨機化的文件名,以避免碰撞,顯然有很多的事情可以做,以生成一個隨機字符串附加。但是,最重要的部分是,您確認您的新文件名也不存在。您可以使用一個循環是這樣的嘗試是:

$RANDOM=$(date | md5) 
filename=$INBOUND/$RANDOM.dat 
while [ -e $filename ]; do 
    $RANDOM=$(date | md5) 
    filename=$INBOUND/$RANDOM.dat 
done 

我並不提倡或反對產生與當前時間的哈希隨機文件名:主要的一點是,你要檢查首先存在該文件,以防萬一。

+0

這個命令似乎有點不錯 - 只有1個文件正在火災中使用 –

+0

啊。哎呀。我們需要爲每個文件指定一個不同的名稱!正如我寫的那樣,每個文件都被複制到相同的名稱。我已經編輯過包含參數佔位符「{}」,並且應該修復它。 –

0

嘗試像

while read i;do 
    echo "file is $i" 
    cp "$i" $INBOUND/$RANDOM.dat 

done < <(find . -name '*Source*.dat') 
1

如果所有文件都在相同的目錄級別,如您的示例中所示,則不需要find。例如,

for i in */*Source*.dat; do 
    cp "$i" $INBOUND/$RANDOM.dat 
done 

將正確記號化,並找到正確的文件,只要它們都在目錄中它們是當前目錄的孩子。

由於@chepner在評論中指出,如果你有bash的V4可以使用**

for i in **/*Source*.dat; do 
    cp "$i" $INBOUND/$RANDOM.dat 
done 

應該找到完全相同的文件作爲find會,沒有標記化問題。

+0

'bash' 4引入了**操作符,即使文件存在於子目錄中:'for我in **/* Source * .dat ; do' – chepner