2017-05-08 56 views
1

我有80雙以下類型的文件的組合擴展在擊循環腳本的索引:在具有通配符和一個下劃線

170309-N701-S517_S1_L001_R1_001.fastq.gz 
170309-N701-S517_S1_L001_R2_001.fastq.gz 
170309-N701-S502_S2_L001_R1_001.fastq.gz 
170309-N701-S502_S2_L001_R2_001.fastq.gz 
170309-N701-S503_S3_L001_R1_001.fastq.gz 
170309-N701-S503_S3_L001_R2_001.fastq.gz 
.. 
170309-N710-S507_S79_L001_R1_001.fastq.gz 
170309-N710-S507_S79_L001_R2_001.fastq.gz 
170309-N710-S508_S80_L001_R1_001.fastq.gz 
170309-N710-S508_S80_L001_R2_001.fastq.gz 

本質上,一對包括以下文件:

170309-N701-S517_S<ID>_L001_R1_001.fastq.gz 
170309-N701-S517_S<ID>_L001_R2_001.fastq.gz 

其中ID從1變化到80。

我想創建80子文件夾名爲S1..S80並把每對在相應的文件夾中,例如

170309-N701-S517_S1_L001_R1_001.fastq.gz 
170309-N701-S517_S1_L001_R2_001.fastq.gz 

去到子文件夾S1

170309-N701-S502_S2_L001_R1_001.fastq.gz 
170309-N701-S502_S2_L001_R2_001.fastq.gz 

去到子文件夾S2

等。

我寫了下面的腳本:

#!/bin/bash 
for i in {1..80} 
do 
    mkdir S$i 
    mv "*_S"$i"_*" S$i 
done 

但預計它沒有工作。它創建了子文件夾S1..S80。但是,它沒有移動任何文件。它生產而不是

mv: cannot stat `*_S1_*': No such file or directory 
mv: cannot stat `*_S2_*': No such file or directory 

等等。

我在做什麼錯?你能糾正劇本嗎?

+3

Globes不會在引號中展開,請將引號刪除。 – 123

+0

@ 123刪除引號也無法按預期工作。它移動第一個文件夾S1中的所有文件。所有剩餘的文件夾都是空的。 – Nick

+1

你的下劃線導致搜索問題,因爲它們不會被引用並且需要被轉義。該行應該是'mv * \ _ $ i \ _ *' – JNevill

回答

2

你想要做的與mv "*_S"$i"_*" S$i行被稱爲variable expansion,如果你作爲擴展的一部分想要連接變量與其他字符,你需要讓BASH知道什麼是變量,什麼是一個普通的字符。您可以通過將變量名稱放在花括號中來完成此操作。 E.g:

var=FOO 
echo "BAR ${var} BAZ" 
# BAR FOO BAZ 

在循環的情況下:

touch \ 
    170309-N701-S517_S1_L001_R1_001.fastq.gz\ 
    170309-N701-S517_S1_L001_R2_001.fastq.gz\ 
    170309-N701-S502_S2_L001_R1_001.fastq.gz\ 
    170309-N701-S502_S2_L001_R2_001.fastq.gz\ 
    170309-N701-S503_S3_L001_R1_001.fastq.gz\ 
    170309-N701-S503_S3_L001_R2_001.fastq.gz 

for i in {1..80} 
do 
if test -n "$(find . -maxdepth 1 -name "*_S${i}_*" -print -quit)" 
then 
    mkdir "S${i}" 
    mv *"_S${i}_"* "S$i" 
fi 
done 

這IF-THEN-Fi無線位是那裏只是爲了避免目錄中不存在的文件。完全可選。

還要注意的是通配符的字符*必須按順序使用mv工作中使用未加引號,因爲裏面"..."'...'*作爲一個文字處理。
但是,在find命令中會看到一個例外情況,其中雙引號之間的內容將在傳遞到find時展開。爲避免這種情況下的擴展,參數可以包含在單個報價('...'

+2

要明確 - 當且僅當緊跟在後面的字符(如下劃線)在shell變量名中有效時,這是必需的。 –

+1

'find'在性能上有點貴,並且意味着你使用了兩種不同的glob機制('find'在那裏,而shell在'mv'之後有幾行 - 如果你啓用了shell extglobs ,以及更有趣的glob表達式,它們可能不匹配)。我建議'匹配=(* _S「$ i」_ *);如果[[-e $ {匹配[0]} || -L $ {matches [0]}]];那麼...'爲了避免外部命令的啓動成本,並確保你可以在稍後'mv'$ {matches [@]}「」S $ i「',重新使用單個glob操作的結果而不是重新計算它.. –

+0

@CharlesDuffy:如果我從頭開始寫這個例程,它會看起來相當不同。我發佈的只是最小的努力改進。 – AkselA

相關問題