2012-01-17 2 views
15

Мне нужно переименовать 45 файлов, и я не хочу делать это один за другим. Это имена файлов:Переименование кратных файлов с помощью цикла bash

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 

Но это не сработает. Можете ли вы сказать мне, почему, или дать другое быстрое решение?

Спасибо!

ответ

20

Несколько ошибок здесь:

  • NEWNAME = должно быть без пробелов. Здесь bash ищет команду с именем NEWNAME, и это терпит неудачу.
  • Вы анализируете вывод ls. это плохо, если у вас есть файлы с пробелами. Bash может составить себе список файлов с оператором glob *.
  • Вы не избежите "$i" и "$NEWNAME". Если какое-либо из них содержит пробел, он делает два аргумента для mv.
  • Если имя файла начинается с тире mv будет считать, что это переключатель. Используйте команду --, чтобы остановить обработку аргументов.

Try:.

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

+0

Я не удалили мой комментарий, но я видел, как ты уже ответил выше. Благодарю. – nickd

+0

приятно, используя '/%' и '--' для' mv'. Я бы, вероятно, включил расширение в цикле 'for',' для i в chr * .fasta' – c00kiemon5ter

+0

Спасибо за ваш полный ответ! – Geparada

7
for f in chr*.fasta; do mv "$f" "${f/%.fasta/.fa}"; done 
+0

не будет работать, если в именах файлов есть пробелы. – Benoit

+0

+1, разнообразие выбора – bobah

+0

Хотя это будет работать с данными, как насчет пробелов в файлах или файлов, содержащих '.fasta' в их имени файла, а не только как их расширение? многие вещи могут ошибаться здесь – c00kiemon5ter

6

Если у вас есть команда rename, вы можете сделать:

rename .fasta .fa chr*.fasta 
+0

Я буду использовать эту команду в следующий раз, спасибо! – Geparada