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

Я пытаюсь изменить jpg-файлы с именем и точкой в ​​начале и с отсутствующей точкой до конца (например: . Startjpg to Start.jpg

Точка делает файлы скрытыми от sed а ls -al перечисляет эти файлы, поэтому я передаю ls -al в sed . Я прочитал много руководств в Интернете, и я всегда получаю эту ошибку

 sed: -e expression #1, char 6: unknown command: `/' 

я пробовал

 ls -al | sed -r '/^\./*.*/g' ls -al | sed -r '/^\.//g' ls -al | sed -r '/.*/[\.]g' ls -al | sed 's/^\./\\1*./g' 

и многие другие и даже многие другие.

также мне нужно изменить filejpg на file.jpg

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

 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 

Чтобы разбить этот patter: jpg$ означает «заканчивается на« jpg ». (?<!\.) Означает, что «до этого нет jpg». Это мешает вам сменить foo.jpg на foo..jpg , что было бы глупо.

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

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

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

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

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

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

-type f ограничит только файлы. Разумеется, вы также можете использовать любые другие варианты поиска.

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

Эта задача лучше подходит для однострочного bash (предполагая, что это ваша оболочка). Переименовать что-то вроде . filejpg . filejpg to 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 . -name "*.jpg" find . -name "*.jpg" . Обычно это выводит каждый файл на новую строку. -print0 этого -print0 он отделяет совпадения нулевым символом. Это позволяет правильно обрабатывать имена файлов с пробелами, когда мы передаем выходные данные следующим командам.

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

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

Циклы while заставляют read итеративно присваивать значения «file» для каждого подходящего имени файла. Выполнение и done являются частью стандартного синтаксиса bash для цикла while:

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

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

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