переименовать несколько файлов на основе другого файла

или просто так, без sed и прочего

tail -1 list && cat list
-1
19.04.2021, 23:02
4 ответа

Если вы работаете на компьютере с 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

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

0
28.04.2021, 22:51

Чистое 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
0
28.04.2021, 22:51

В случае, если утилита 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
0
28.04.2021, 22:51

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

Использование/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.

Проверка конфликтов имен не выполняется.

0
28.04.2021, 22:51

Теги

Похожие вопросы