Переименовывать файлы рекурсивно Mac OSX

Попытка переименовать кучу файлов.

Я могу переименовать любые экземпляры foo со строкой в ​​текущем каталоге с помощью:

ls . | awk '{print("mv "$1" "$1)}' | sed 's/foo/bar/2' | /bin/sh

Что я могу добавить, чтобы сделать его рекурсивным?

Изменить/Мое решение

Я не знаю/понимаю этот материал типа оболочки, поэтому я сделал это с некоторыми (довольно грязными) Ruby:

5.times do
  Dir["**/*"].each do |f|
    file_name = File.absolute_path f
    should_rename = file_name.include? "yolo"
    new_file_name = file_name.gsub("yolo", "#{@project_name}")
    File.rename(f, new_file_name) if (should_rename and File.exists? f)
  end
end

Ответ 2

Утилита rename также предоставляет синтаксис, который не требует знания регулярного выражения. После установки утилиты

brew install rename

Опция -s заменит первый экземпляр foo на bar:

find . -exec rename -s 'foo' 'bar' {} +

И опция -s заменит все экземпляры:

find . -exec rename -S '_' ' ' {} +

Это действительно то же самое решение, что Marcel Steinbach, приведенный выше, просто другой синтаксис.

Ответ 3

Ответ на вопрос "Как мне сделать X рекурсивно в некоторой файловой структуре" почти всегда используется find. В этом случае возможно также в сочетании с циклом for. В следующем примере рекурсивно прокручиваются файлы, соответствующие шаблону foo в текущем каталоге.

thedir=./
for file in $(find $dir -type f -name foo); do
    # rename $file here
done

В зависимости от вашей желаемой схемы переименования и того, как вы хотите выразить переименование, тело цикла будет иметь разные команды переименования.

Простое переименование каждого файла с именем foo до bar приведет к одному файлу bar, и это не то, что люди обычно хотят. Переменная $file содержит относительный путь к файлу, поэтому в differents bar будут разные пути.