Прокручивать список терминов и файлов пакетного переименования - PullRequest
1 голос
/ 06 июня 2019

РЕДАКТИРОВАТЬ : В ходе работы над этим вопросом и его повторного редактирования я смог заставить его работать. Однако я уверен, что есть лучший способ сделать это, поэтому я оставляю это, чтобы услышать от более опытных.

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

company_a_results_30d.py
company_a_results_90d.py
company_a_results_120d.py
company_a_results_all_time.py

Мне нужно сделать копии, где company_a заменено на company_b, company_c .... и т. Д. (Следующий шаг - найти и заменить несколько терминов в файлах, но это мне удалось сделать с помощью Perl-скрипта.)

Я уверен, что это возможно с помощью bash-скрипта и mv, но я не совсем освоил его. Что-то вроде:

#!/usr/bin/env bash
my_array=(company_b company_c company_d)
for i in "${my_array[@]}" 
do
  for file in *.py
  do
    cp "$file" "${file/company_a/$i}"
  done
done

Я бы предпочел решение, совместимое с zsh, которым я и пользуюсь.

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Баш

Слегка изменено с ответ ОП :

#!/usr/bin/env bash
set -x      # So you can see what's happening - feel free to omit

company_a_files=(company_a*.py)  # <== Save the list of files first

my_array=(company_b company_c company_d)
for i in "${my_array[@]}" 
do
  for file in "${company_a_files[@]}"    # <== Use the saved list
  do
    cp "$file" "${file/company_a/$i}"
  done
done

Когда внутренний цикл в ответе OP запускается for file in *.py, шар получит все, что угодно company_b & c. файлы уже созданы. Таким образом, вы получаете много set -x выводов вроде:

+ cp company_b_1.py company_b_1.py
cp: 'company_b_1.py' and 'company_b_1.py' are the same file

Вместо этого сначала сохраните глобус файлов company_a в массив оболочки, а затем цикл по этому массиву.

Perl

Как однострочник для Perl 5.14 +:

 perl -MFile::Copy=copy -E 'for my $file (@ARGV) { copy $file, $file =~ s/company_a/$_/r foreach qw(company_b company_c company_d) }' company_a*.py

Версия Perl переключает порядок цикла по сравнению с версией bash. Для каждого файла, указанного в командной строке (for ... @ARGV), он по очереди копирует этот файл в каждый файл с измененным именем (foreach).

$file =~ s/company_a/$_/r - это неразрушающая (/r) замена в $file (имя файла), которая изменяется с company_a на $_ (текущее значение с foreach).

1 голос
/ 06 июня 2019

Это было решение, которое я придумал:

#!/usr/bin/env bash
my_array=(company_b company_c company_d)
for i in "${my_array[@]}" 
do
  for file in *.py
  do
    cp "$file" "${file/company_a/$i}"
  done
done
...