Как переименовать файлы с пробелами, используя оболочку Linux?

28

Я назвал несколько файлов с пробелами в них, и я хочу заменить пробел на _. Однако каждый раз, когда я пишу в оболочке команду с именем файла (например Spring 2011), оболочка не распознает файл или каталог.

Что я могу сделать по этому поводу? Есть ли способ использовать символ Юникода для пробела?

Фил Браун
источник
для программного переименования N файлов используйте bashцикл for: см. мое решение здесь .
Тревор Бойд Смит

Ответы:

33

Выйти из пространства, например Spring\ 2011, или использовать кавычки, например 'Spring 2011'. В будущем, как правило, плохая идея использовать имена файлов с пробелами в них в любой * NIX.

Если у вас есть rename, вы можете использовать это:

rename ' ' '_' [filenames...]
Рэйф Кеттлер
источник
1
Вы знаете, есть ли способ сделать это для всех файлов одновременно?
3
Почему это плохая идея? Программист обязан правильно обрабатывать имена файлов.
Гленн Джекман
1
@rafe, на самом деле это склонность к ошибкам, чтобы не обрабатывать имена файлов должным образом. Дополнительные усилия возникают при необходимости отладки скрипта, когда вы просто забыли процитировать переменные, содержащие имя файла.
Гленн Джекман
3
Этот ответ, похоже, не работает (по крайней мере, на Ubuntu 12.04 LTS). Ответ от unutbu работает нормально, хотя.
ДНК
1
это только сделало первый пробел для меня ... что не полезно (у меня есть renameверсия 2.23)
Тревор Бойд Смит
30

Если на вашем компьютере есть команда переименования , тогда все пробелы в файле / директории в текущем рабочем каталоге будут заменены на подчеркивания:

rename 's/ /_/g' *
unutbu
источник
Подтвержден для работы в Ubuntu 12.04
anthonygore
1
не работал для меня ... я получил ошибку "переименовать: недостаточно аргументов". У меня есть версия rename --version rename from util-linux 2.23.2.
Тревор Бойд Смит
-bash: /usr/bin/rename: Argument list too long
nmz787
24

Если у вас нет renameили вы предпочитаете использовать только оболочку:

for f in *\ *; do mv "$f" "${f// /_}"; done

Сломано:

  • *\ *выбирает все файлы с пробелом в имени в качестве входных данных для forцикла.
  • Кавычки "$f"важны, потому что мы знаем, что в имени файла есть пробел, и в противном случае он будет выглядеть как 2+ аргумента mv.
  • ${f//str/new_str}специфичная для bash функция подстановки строк Все экземпляры strзаменены на new_str.
blahdiblah
источник
2
это работает, но для меня это только заменяет первый пробел. если я использую for f in *\ *; do mv "$f" "${f// /_}"; doneэто работает
billynoah
@billynoah Хороший улов, обновлено.
Blahdiblah
@blahdiblah Большое спасибо! Вы просто сэкономили мне столько времени!
Партизанский
@blahdiblah ваше решение намного элегантнее моего решения . отличная работа. Я не думал, что цикл for будет работать ... поэтому я сделал глобус за пределами цикла for.
Тревор Бойд Смит
3

mv "Spring 2011.file" Spring_2011.file должен указать командной строке принять строку в кавычках в качестве одного ввода.

rockerest
источник
Это единственный ответ, который я мог получить на работу.
Blakeoft
1

Чтобы программно переименовать N файлов, вы можете использовать простой bashцикл for.

#!/bin/bash

set -eux

# find all your files by using a `grep` pattern
pattern="insert_filename_pattern_here" # you must enter your filename pattern here

# create an array of filenames and split on newlines
IFS=$'\n'
tmp=($(ls | grep ${pattern}))
unset IFS

# for each filename
for filename in "${tmp[@]}"; do
    # rename the filename to use "_" character instead of a " " character
    mv -v "${filename}" "${filename// /_}"
done

Если у вас меньше , чем 5 имен файлов, то вы можете вручную ввести во всех именах файлов и использовать renameкоманду как выше решение предлагает. Но для меня ... Я предпочитаю программное решение ... даже когда есть только 4 файла.

п.с.

если вы не знакомы с Bashрасширением параметров (то есть ${filename// /_}), вы можете использовать renameкоманду:

if ((0)); then
    mv -v "${filename}" "${filename// /_}"
else
    rename ' ' '_' "${filename}"
fi
Тревор Бойд Смит
источник