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

$HOME/bin, . и ./bin обычно смотрятся как угроза безопасности.

Для $HOME/bin это - проблема некоторого "взломщика", продвигающего некоторый сценарий (скажите, что сценарий назвал нано) к тому каталогу, затем это ожидает, пока Вы не выполняете что-то как sudo nano /etc/hosts получить мгновенный корневой доступ (изменяют нано на vi, emacs, безотносительно; команда не важна, это - полезная нагрузка, которую это может выполнить).

Для . и ./bin, это - все еще та же проблема: добавление дополнительной программы, работающей из неправильного каталога.

Если те./bin/command находятся в различных каталогах вместо/usr/local/bin (предпочтительное решение для новых, локальных сценариев), это - потому что они делают разные вещи; что, если Вы выполняете неправильный?

При именовании команд тем же путем (давайте назовем затем обновление, фиксацию, очистку, и т.д.), можно работать над каталогом, то Вы получаете один телефонный вызов и изменение в другом для быстрой проверки. После зависания Ваш мозг попытается возобновить то, что Вы делали, и большинство времен забудет, что быстрый "CD", который Вы сделали (особенно, если все на экране, кажется, указывает на корректный каталог) и заканчивает работать, команда на неправильном каталоге (скажите, что сценарий очистки, который стирает всю Вашу работу месяца).

Это могло бы посмотреть невинная ошибка, но они происходят каждый день со многими людьми!:)

Хорошее обходное решение (или лучшее решение) должны использовать псевдоним:

alias proj1-cleanup=/srv/proj1/bin/cleanup

и прибавьте сценарий корректное cd для проверки это работает на корректном каталоге.

Таким образом, играющий с $HOME/.alias для добавления различных сценариев, Вам нужно, у Вас есть различные команды, чтобы сделать разные вещи, и даже если кто-то взламывает Ваш браузер для создания a $HOME/bin/ls файл или некоторый локальный пользователь создают bin/ls файл на любом каталоге, они никогда не будут выполняться как Ваши неподвижные точки пути к корректным командам.

Но эй, это - личный выбор; Вы - тот, который знает то, что Ваши локальные риски и что делают команды.

8
23.07.2014, 20:32
3 ответа

С помощью утилиты Perl rename (которая называется rename в Debian и друзьях, включая Ubuntu, это может быть предисловие в другом месте):

rename -n 's/(?<!\.)jpg$/.jpg/' *  # -n makes it show you what it'll do,
                                   # but not actually do it. Remove the -n to
                                   # actually rename

Чтобы разбить эту болтовню: jpg$ означает "заканчивается на "jpg"". (? означает 'нет ни одной точки перед этим 'jpg''. Это не позволяет вам изменить foo.jpg на foo...jpg, что было бы глупо.

* - это обычный шаблон оболочки; rename берет список файлов для рассмотрения переименования. Вы, конечно же, можете сделать /путь/к/до/dir/*, передать список имен файлов, использовать совместно с find и т.д.

Удалить точки и пробелы с начала тоже довольно просто:

rename -n 's/^[. ]+//' *          # trying -n first is good practice

Это удалит все точки и пробелы с начала. Повернется ... . foo в foo.

Обычно расширение оболочки * не дает файлов с именем, начинающимся с точки (скрытые файлы). Одним из вариантов является использование .*; это также даст две специальные записи . (текущий каталог) и ... (родительский каталог). В этом случае это должно быть безобидно; первая команда проигнорирует их (они не заканчиваются на jpg); вторая команда попытается переименовать их, но это должно привести только к ошибке. Альтернативой является поиск:

find -type f -exec rename -n 's/^[. ]+//' '{}' +

-тип f будет ограничен только файлами. Конечно, можно использовать и другие опции find.

.
9
27.01.2020, 20:11

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

0
27.01.2020, 20:11

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

Эта задача лучше подходит для bash one-liner (предполагая, что это ваша оболочка). Чтобы переименовать что-то вроде . filejpg в file.jpg, используйте следующее:

find . -name '. *' -print0 | while read -d $'\0' file; do short_file=${file%jpg}.jpg; mv "$file" "${short_file:4}"; done

Объяснение

find - это программа, которая возвращает пути к файлам, которые соответствуют определённому свойству файла, в данном случае - имени файла. Если бы все, что вы хотели узнать, это что .jpg файлы находятся в поддиректориях вашего текущего пути, вы бы сделали find . -имя "*.jpg". Обычно это выводит каждый файл в новой строке. С помощью -print0 он отделяет совпадения нулевым символом. Это позволяет правильно обрабатывать имена файлов с пробелами, когда мы передаем вывод следующим командам.

Символ | известен как канал. Он говорит оболочке взять вывод команды слева и передать его в качестве входа в команду справа, в данном случае, команда read в цикле во время цикла .

Команда read используется для получения вывода find и присвоения его переменной, файлу file. Обычно это присваивает значения файлу find каждому слову одновременно, но -d $'\0'$ вызывает разделение присваиваемых значений нулевым символом (совпадает с тем, как мы делили файлы в find с помощью флага -print0).

В то время как циклы приводят к тому, что считывают к итеративному присвоению значений "файлу" для каждого совпадающего имени файла. do и done являются частью стандартного синтаксиса bash на некоторое время цикла:

while <something is true>; do
    <run some commands>
done

В этом случае наша команда "run some command" сначала исправляет расширение имени файла и присваивает его новой переменной: short_file=${file%jpg}.jpg меняет . filejpg на . file.jpg. Затем он запускает mv для переименования файла, удаляя . в начале имени файла с расширением, исправленным: mv "$file" ${short_file:2}.

4
27.01.2020, 20:11

Теги

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