Использование команды mv не распознает * как шаблон

У меня есть этот скрипт, и я знаю, что в нем работает команда awk, но когда я хочу сохранить выходные данные, используя то же имя файла, который использовался для выполнения задачи, используя mv командовать * не используется как подстановочный знак, а вместо этого как символ, и я получаю файл с таким именем:

Algeria_BER _ * _ sites.txt

Сценарий:

#!/bin/bash

for i in Algeria_BER 
do

 echo awk 'FNR==NR{a[++i]=$0;next} {print a[FNR] RS $0}' \
     reduced_filt_MAF_b37_chr1_${i}_ldhat.txt_names ${i}_*_sites.txt > $$.tmp &&
   mv $$.tmp "${i}_*_sites.txt"

done

2 ответа

mv команда не распознает * подстановочные; оболочка делает.

Это:

foo*.txt

расширяется до списка всех файлов в текущем каталоге, имена которых начинаются с foo и заканчивается .txt, Если вы пройдете foo*.txt в качестве аргумента mv, mv Команда никогда не видит *; он видит только список файлов.

Это означает, что если у вас есть файлы foo1.txt а также foo2.txt, этот:

mv foo*.txt bar*.txt

не будет переименовывать foo1.txt в bar1.txt а также foo2.txt в bar2.txt -- так как bar*.txt можно расширить только до списка файлов, которые уже существуют. Если нет соответствующих файлов bar*.txtто вышеизложенное расширяется до:

mv foo1.txt foo2.txt bar42.txt

что является ошибкой, если bar42.txt случается быть каталогом. Он будет расширяться различными способами в зависимости от того, какие файлы существуют в данный момент, и ни один из них, вероятно, не будет тем, что вы хотите.

Если нет файлов, соответствующих данному шаблону, поведение зависит от оболочки и ваших текущих настроек. В bashс настройками по умолчанию подстановочный знак просто не раскрывается - вероятно, поэтому вы получаете файл с * в его названии.

Существуют инструменты массового переименования, которые будут делать то, что вы хотите (я сам ими не пользовался).

Другой подход, который я часто использую, - перечислить файлы в текстовый файл, отредактировать файл вручную, а затем запустить его как скрипт. Например, я мог бы сделать это:

ls foo*.txt > tmp

затем вручную отредактируйте tmp превратить каждую строку в команду, которая делает то, что я хочу:

foo1.txt
foo2.txt

->

mv foo1.txt bar1.txt
mv foo2.txt bar2.txt

и затем выполните команду:

. ./tmp

Проблема заключается в цитировании. Шаблон Glob должен быть вне кавычек, поэтому вам нужно:

"${i}_"*"_sites.txt"
Другие вопросы по тегам