Если вы работаете на компьютере с Linux или иным образом имеете доступ к команде perl rename (, она может называться rename
, prename
или perl-rename
в зависимости от операционной системы )и при условии, что вы можете никогда не используйте пробелы или другие пробелы в идентификаторе, вы можете сделать:
while read id hom; do
rename -n "s/^$id/$hom/" "$id".*
done < names.homologs.txt
Это просто напечатает то, что должно быть сделано, но на самом деле ничего не переименует. После того, как вы убедились, что он делает то, что вы хотите, запустите его снова без опции -n
, чтобы действительно внести изменения.
Кроме того, вы также можете сделать это в оболочке:
while read id hom; do
for file in "$id".*; do
newFile=$(printf '%s\n' "$file" | sed "s/$id/$hom/")
mv -- "$file" "$newFile"
done
done < names.homologs.txt
Но обратите внимание, что это предполагает, что не будет конфликтов имен (, если новое имя файла соответствует имени существующего файла, то существующее будет закончено -написано ), никаких новых строк в ваши имена файлов (, что действительно должно быть безопасным предположением с файлами втиски ).
Чистое bash
решение, при условии, что @terdon говорит, что в именах файлов нет странных символов и нет огромного количества гомологов:
#!/usr/bin/env bash
declare -a homologs
while read key val
do {
homologs["$key"]="$val"
} done < names.homologs.txt
while read file
do
# key is the part before the dot
key="${file%%.*}"
# end is part after the first dot to the end
end="${file#*.}"
printf 'mv -- "%s" "%s.%s"\n' "${file}" "${homologs["$key"]}" "$end"
done
В случае, если утилита rename не установлена, всегда можно накатить свою, но без наворотов:
perl -le 'local $/;
my %h = <STDIN> =~ /^(.*) (.*)$/mg;
rename $_, s/^[^.]+/$h{$&}/r
for @ARGV;
' *cram* < names.homologs.txt
С файлом гомологов на стандартном входе Pearl, откуда мы инициализируем хэш сопоставления имен и применяем его в последующей команде переименования.
Мы можем попробовать сделать это с помощью sed, так как в именах файлов нет новых строк
sed -Ee '
1i\
h
s|\S+|s/^[.][/]&[.]/|
s||.\\/&./;ta|2
$a\
:a\
G\
s/(.*)\\n(.*)/\\2 \\1/
' names.homologs.txt > genMvPairs
find. -maxdepth 1 -type f -name '*.cram*' |
sed -Ef genMvPairs - | xargs -n2 -t mv -f
Это оказалось похоже на вторую половину ответа тердона , но я использую более безопасный и гораздо более быстрый способ вычисления новых имен файлов.
Использование/bin/sh
:
#!/bin/sh
while read -r id homolog; do
for oldname in "$id".*; do
[ -e "$oldname" ] || continue
newname=$homolog.${oldname#$id.}
mv -- "$oldname" "$newname"
done
done <names.homologs.txt
Предполагается, что файл, который мы хотим переименовать, находится в текущем каталоге. Сценарий считывает две строки из каждой строки файла names.homologs.txt
в две переменные id
и homolog
.
Для каждого id
он пытается перебрать файлы, имена которых соответствуют "$id".*
в текущем каталоге. Для каждого такого файла, если он вообще существует, имя изменяется путем замены части $id.
, которая, как мы знаем, находится в начале строки, на $homolog.
. Затем для фактического переименования файла используется утилита mv
.
Проверка конфликтов имен не выполняется.