web-dev-qa-db-ja.com

bashループで複数のファイルの名前を変更する

45個のファイルの名前を変更する必要がありますが、1つずつ変更したくありません。これらはファイル名です:

chr10.fasta         chr13_random.fasta  chr17.fasta         chr1.fasta          chr22_random.fasta  chr4_random.fasta  chr7_random.fasta  chrX.fasta
chr10_random.fasta  chr14.fasta         chr17_random.fasta  chr1_random.fasta   chr2.fasta          chr5.fasta         chr8.fasta         chrX_random.fasta
chr11.fasta         chr15.fasta         chr18.fasta         chr20.fasta         chr2_random.fasta   chr5_random.fasta  chr8_random.fasta  chrY.fasta
chr11_random.fasta  chr15_random.fasta  chr18_random.fasta  chr21.fasta         chr3.fasta          chr6.fasta         chr9.fasta         
chr12.fasta         chr16.fasta         chr19.fasta         chr21_random.fasta  chr3_random.fasta   chr6_random.fasta  chr9_random.fasta
chr13.fasta         chr16_random.fasta  chr19_random.fasta  chr22.fasta         chr4.fasta          chr7.fasta         chrM.fasta

拡張子「.fasta」を「.fa」に変更する必要があります。私はそれをするためにbashスクリプトを書こうとしています:

for i in $(ls chr*)

do

NEWNAME = `echo $i | sed 's/sta//g'`

mv $i $NEWNAME

done

しかし、それは機能しません。理由を教えてもらえますか、または別の簡単な解決策を教えてください。

ありがとう!

21
Geparada

ここでいくつかの間違い:

  • NEWNAME =にはスペースを入れないでください。ここでbashはNEWNAMEという名前のコマンドを探していますが、失敗します。
  • lsの出力を解析します。スペースを含むファイルがある場合、これは悪いことです。 Bashはglob演算子*
  • 逃げられない"$i"および"$NEWNAME"。それらのいずれかにスペースが含まれている場合、mvに対して2つの引数が作成されます。
  • ファイル名がダッシュmvで始まる場合、それはスイッチであると考えられます。使用する --は、引数の処理を停止します。

試してください:

for i in chr*
do
  mv -- "$i" "${i/%.fasta/.fa}"
done

または

for i in chr*
do
  NEWNAME="${i/%.fasta/.fa}"
  mv -- "$i" "$NEWNAME"
done

"%{var/%pat/replacement} "は、変数のpat最後のみを探し、replacementに置き換えます。

30
Benoit
for f in chr*.fasta; do mv "$f" "${f/%.fasta/.fa}"; done
9
Chris Dodd

rename コマンドがある場合、次のことができます。

rename .fasta .fa chr*.fasta
7
dogbane