我整天從教程到現成的 bash 腳本,但找不到我需要的東西。此外,我之前從未寫過 bash 腳本...:/
這是我的問題(參考全金屬外殼:“有很多喜歡它,但這個是我的”):我有一個包含 120 個檔案的目錄,這些檔案以三聯體形式出現(粗體我標記了每個檔案三聯體的獨特之處):
GSM6025 613 _SJWLM 030043 _D1_barcodes.tsv
GSM6025 613 _SJWLM 030043 _D1_features.tsv
GSM6025 613 _SJWLM 030043 _D1_matrix.mtx
GSM6025 615 _SJWLM 071563 _D1_barcodes.tsv
GSM6025 615 _SJWLM 071563 _D1_features.tsv
GSM6025 615 _SJWLM 071563 _D1_matrix.mtx
...
我想要一個 bash 腳本,它根據三元組唯一字串(fe '613'、'615')創建具有名稱的新目錄移動三個相應的檔案(*barcode.tsv、*features.tsv、*matrix.mtx ) 到相應的目錄并重命名它們,以便檔案僅稱為“barcode.tsv”、“features.tsv”和“matrix.mtx”。
我嘗試使用 for 回圈,但我對 bash 腳本和第二行之外的內容非常空白,老實說,這對我來說都是胡言亂語(現在)......:/
`#!/bin/bash
for f in *.{tsv,mtx}
do
...
done`
我很感激任何幫助!
uj5u.com熱心網友回復:
您可以使用sed將檔案名拆分為其組件,如下所示
file='GSM6025615_SJWLM071563_D1_barcodes.tsv'
eval $(sed -E 's/(GSM....)([0-9] )_(.*)_(.*)_(.*)\.tsv/n=\2;f=\5;/' <<< "$file")
echo $n
615
echo $f
barcodes
eval允許您獲取sed(n和f變數賦值)的輸出并將其轉換為變數。
uj5u.com熱心網友回復:
試試這個Shellcheck -clean 代碼(也許先在你的目錄的副本上!):
#! /bin/bash -p
shopt -s nullglob
for file in GSM6025[0-9][0-9][0-9]_*_{features.tsv,matrix.mtx,barcodes.tsv}
do
dir=${file#GSM6025}
dir=${dir%%_*}
newfile=${file##*_}
mkdir -p -v -- "$dir"
mv -n -v -- "$file" "$dir/$newfile"
done
shopt -s nullglob當沒有匹配項時,使 glob 擴展為空(否則它們擴展為 glob 模式本身,這在程式中幾乎從不有用)。- 請參閱洗掉部分字串(BashFAQ/100(如何在 bash 中進行字串操作?))以了解
${file#GSM6025}等。
uj5u.com熱心網友回復:
建議一行awk腳本:
awk '{d=substr($1,8);printf("mkdir -p %s;mv %-38s %s\n",d,$0,d"/"$4);}' FS="_" <<< $(ls *.csv *.mtx)
如果輸出命令令人滿意,請運行輸出:
bash <<< $(awk '{d=substr($1,8);printf("mkdir -p %s;mv %-38s %s\n",d,$0,d"/"$4);}' FS="_" <<< $(ls *.csv *.mtx))
awk腳本解釋:
BEGIN{FS="_"} # set awk field seperator to "_"
{ # for each file name input
dir=substr($1,8); # extract dir name from 1st field
printf("mkdir -p %s;mv %-38s %s\n", # format output command with printf
dir, # 1st argument dir value
$0, # 2nd argument unchanged input file name
dir"/"$4); # 3rd argument dir appended with 4th field
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/485465.html
