1

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

  • "abc" в имени файла заменено на "def" *** Строка "abc" может быть во многих файлах
  • "jkl" в имени файла заменено на "srt" *** Строка "jkl" может быть во многих файлах
  • "pqr" в имени файла заменено на "xyz" *** Строка "pqr" может быть во многих файлах

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

rename Path\OriginalName1 NewName1
rename Path\OriginalName2 NewName2

Проблема с описанной выше процедурой состоит в том, что это занимает много времени, так как файлов много. И поскольку я использую Excel 2003, есть ограничение на количество строк. Мне нужен скрипт в пакетном режиме, как:

replacestr  abc with def
replacestr  pqr with xyz

в одном каталоге. Будет ли это лучше делать в Unix-скрипте?

4 ответа4

3

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

#!/bin/bash

(( $# != 2 )) && exit 1

for f in *; do
  newf="${f//$1/$2}"
  if [[ $f != $newf ]]; then
    mv "$f" "$newf"
  fi
done

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

Использование, если сохранено как replacestr и данный режим должен быть выполнен:

$ ./replacestr abc def

Он будет пытаться переименовать все. Вы можете использовать [[ ! -f $f ]] чтобы пропустить не файл. Вы также можете обернуть его в функцию и получить его из вашего ~/.bashrc если вам это нужно очень часто.

1

Любой сценарий, который вы используете, может быть потенциально опасным, но это работает для меня в ограниченном масштабе (я только коснулся около 15 файлов и быстро сделал csv abc, 123 \n def, 456 и т.д.).

После этого я бы сделал быструю резервную копию, протестировал ее на нескольких, а затем развернул.

Предположения:
- Excel экспортируется в CSV с форматом oldname,newname в каждой строке
-Вы находитесь в оболочке bash.
-Все в одном каталоге
-Это все файлы (вы можете изменить сценарий на dirs, изменив -type f на -type d

#!/bin/bash
inputfile=${1}
while read line
do
    IFS=',' read -a names <<< "${line}"
    for file in `find . -maxdepth 1 -type f -name "*${names[0]}*"`; do
        rename "s/${names[0]}/${names[1]}/" *
    done
done < ${inputfile}

Это будет работать из текущей директории (find .) И работать только на 1 уровне (-maxdepth 1), элементы легко меняются. Надеюсь, что, по крайней мере, вы попадете на правильный путь.

Важно то, что он поддерживает оставшуюся часть имени вашего файла и заменяет только входную строку на выходную. Таким образом, файл 123abc123.null с вводом abc,999 приведет к 123999123.null .

Просто сделайте его исполняемым с помощью chmod +x nameofmyscript.sh и выполните его с помощью ./nameofmyscript.sh input/file/location.csv

0

Вот хорошая инструкция. Есть много получателей и даже сценарий. Я надеюсь, что вы найдете то, что ищете.

На самом деле вы должны изучить регулярные выражения для лучшего понимания темы.

0

В пакетном файле Windows:

@echo off
setlocal enabledelayedexpansion
set needle=%~1
set replace=%~2
pushd %3
for %%i in (*.*) do (
    echo %%i|findstr "%needle%"> nul && (set match=%%i&move /-Y "%%i" "!match:%needle%=%replace%!")
)
popd

Пример синтаксиса: batchrename.bat "abc" "def" ".\bigfolder"

Он работает, изменяя текущий каталог, если он указан, и просматривая его, используя for (используйте флаг /R, чтобы включить подкаталоги). Затем он передает имя файла в команду findstr, которая сравнивает его со строкой иглы. Если совпадение найдено, строка печатается, но подавляется > nul . Если совпадений не найдено, уровень ошибки устанавливается равным единице, после чего && предотвращает выполнение оставшейся части команды.

Переменная %%i затем копируется в %match% , потому что форма итератора не поддерживает замену подстроки. Затем имя файла переименовывается командой move с использованием измененной строки назначения !match:%needle%=%replace%! ,

Обратите внимание, что опечатки или ошибки могут испортить ваши имена файлов. Используйте с осторожностью.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .