$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 файл на любом каталоге, они никогда не будут выполняться как Ваши неподвижные точки пути к корректным командам.
Но эй, это - личный выбор; Вы - тот, который знает то, что Ваши локальные риски и что делают команды.
С помощью утилиты 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.
В качестве альтернативы другим ответам можно использовать графический инструмент GPRename. Он может заменять символы, усеченные имена файлов и т.д. Преимуществом является встроенная функция предварительного просмотра для проверки новых имен файлов перед их переименованием. Но так как она работает на одной директории за раз, будет неудобно использовать ее с многочисленными папками в подкаталогах. Но для менее чем 10 папок это не проблема.
Хотя 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}
.