- Показать имена всех файлов в директории Bash Script
- Введение
- Показать имена всех файлов в директории
- Показать файлы с определёныым расширением
- Получить имя файла без расширения
- Получить только расширение файла
- Преобразовать изображения в формат .webp
- Добавить к названиям файлов суффикс
- Получить имя файла без расширения в Bash
- 1 ответов
- Извлечение имени файла без пути и расширения в bash [дубликат]
- 9 ответов
- Linux bash имя файла без расширения
Показать имена всех файлов в директории Bash Script
Введение
Перед тем как читать эту статью убедитесь, что вы знакомы с содержанием статьи «Основы Bash»
Показать имена всех файлов в директории
#!/bin/bash for file in ./**; do echo » $
Показать файлы с определёныым расширением
Если нужны только файлы с расширением .jpg
#!/bin/bash for file in ./**.jpg; do echo » $
Получить имя файла без расширения
Если нужно только имя файла без расширения
#!/bin/bash for file in ./**.jpg; do filename= » $
Получить только расширение файла
Если нужно только расширение
#!/bin/bash for file in ./**.jpg; do extension=»$
Преобразовать изображения в формат .webp
wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.2.0-linux-x86-64.tar.gz
mkdir webp
cp libwebp-1.2.0-linux-x86-64.tar.gz webp/
tar -xvf libwebp-1.2.0-linux-x86-64.tar.gz
cp -r libwebp-1.2.0-linux-x86-64 libwebp-current
cd libwep-current/bin
pwd
vi
#!/bin/bash for file in ./**.jpg; do filename= » $
Добавить к названиям файлов суффикс
Если нужно сохранить расширение файла, а к оригинальному названию добавить какое-то слово или символ. А сделать это со всеми файлами данного типа в директории
Например в директории есть файлы a.jpg , b.jpg , c.jpg , а нужно сделать из них a—small.jpg , b—small.jpg , c—small.jpg
#!/bin/bash POSTFIX=»—small» # что вы хотите добавить EXT=».jpg» # к каким файлам for file in ./** $EXT ; do fullname= » $
А теперь скрипт, который делает и то и другое, а перед тем как делать проверяет нет ли уже такого файла
Источник
Получить имя файла без расширения в Bash
у меня есть следующие for цикл индивидуально sort все текстовые файлы внутри папки (т. е. создание отсортированного выходного файла для каждого).
это почти идеально, за исключением того, что он в настоящее время выводит файлы в формате:
. тогда как хотелось бы выводить файлы в формате:
это так $
как я могу отделить имя файла от расширения, так что я могу добавить _sorted суффикс между ними, что позволяет мне легко различать оригинальные и сортированные версии файлов, сохраняя при этом расширения файлов Windows нетронутыми?
Я смотрел на то, что может be возможно решения, но мне они кажутся более приспособленными для решения более сложных проблем. Что еще важнее, с моим нынешним bash знание, они идут над моей головой, так что я держу надежду, что есть более простое решение, которое относится к моей скромной for цикл, или же кто-то может объяснить, как применить эти решения к моей ситуации.
1 ответов
эти решения, на которые вы ссылаетесь, на самом деле довольно хороши. Некоторые ответы могут не иметь объяснения, поэтому давайте разберемся, возможно, добавим еще.
указывает, что расширение известно заранее (Примечание: POSIX-совместимые среды чувствительны к регистру, *.txt не соответствует FOO.TXT ). В таком случае
должен возвращать имя без расширения ( basename также удаляет путь к каталогу: /directory/path/filename → filename ; в вашем случае это не имеет значения, потому что $file не содержит такого пути). Для использования инструмента в коде необходима подстановка команд, которая выглядит примерно так: $(some_command) . Команда подстановки принимает вывод some_command , обрабатывает его как строку и помещает в $(…) есть. Ваше конкретное перенаправление будет
вложенные кавычки здесь в порядке, потому что Bash достаточно умен, чтобы знать кавычки в $(…) парные вместе.
это можно улучшить. Примечание basename — это отдельный исполняемый файл, а не встроенная оболочка (в bash run type basename для всех type cd ). Нерест любой лишний процесс обходится дорого, требует ресурсов и времени. Нерест его в петле обычно выполняет плохо. Поэтому вы должны использовать все, что предлагает вам оболочка, чтобы избежать дополнительных процессов. В этом случае решение:
синтаксис описан ниже для более общего случай.
в случае, если вы не знаете расширение:
- $
— $file , но самая короткая строка, соответствующая *. удаляется спереди; - $
— $file , но самая длинная строка, соответствующая *. удаляется спереди; используйте его, чтобы получить только расширение; - $
— $file , но самая короткая строка, соответствующая .* удаляется из конец; используйте его, чтобы получить все, кроме расширения; - $
— $file , но с самой длинной строкой, соответствующей .* удаляется с конца;
сопоставление шаблонов похоже на glob, а не на regex. Это значит * — подстановочный знак для нуля или более символов, ? — это замена одного персонажа (нам не нужны ? в вашем случае, хотя). Когда вы вызываете ls *.txt или for file in *.txt; вы используете тот же шаблон, соответствующий механизм. Узор без подстановочных знаков допускается. Мы уже использовали $
но будьте осторожны:
по этой причине следующая штуковина может быть полезным (но это не так, объяснение ниже):
он работает, идентифицируя все, кроме расширения ( $
Примечание. the . включен в это время. Вы можете получить неожиданные результаты, если $file содержит литерал * или ? ; но Windows (где расширения имеют значение) не дает эти символы в именах файлов в любом случае, так что вам может быть все равно. Однако […] или <…>, если присутствует, может вызвать их собственную схему сопоставления с образцом и сломать решение!
ваше» улучшенное » перенаправление будет:
он должен поддерживать имена файлов с или без расширения, хотя и не с квадратными или фигурными скобками, к сожалению. очень жаль. чтобы исправить это, нужно заключить внутреннюю переменную в двойные кавычки.
действительно улучшенное перенаправление:
двойное цитирование делает $
еще одно (несовершенное) решение, давайте проанализируем его по образовательным причинам:
заменяет первый . с _sorted. . Он будет работать нормально, если у вас есть не более одной точки в $file . Похожий синтаксис $
все еще первоначальное решение для файлов с . выглядит надежной. Решение для без расширений $file тривиально: $
возвращает статус выхода 0 (true) тогда и только тогда, когда содержимое $file переменная соответствует шаблону правой стороны. Шаблон говорит: «есть точка после хотя бы одного символа» или, что то же самое, «есть точка, которая не находится в начале». Дело в том, чтобы лечить скрытые файлы Linux (например, .bashrc ), а без расширений, если есть другое точка где-то.
Примечание нам нужно [[ здесь, а не [ . Первый более мощный, но, к сожалению,не портативный; последнее является портативным, но слишком ограниченным для нас.
логика теперь выглядит так:
после этого, $file1 содержит желаемое имя, поэтому перенаправление должно быть
и весь код ( *.txt заменить * , чтобы указать нам работа с любым расширением или без расширения):
это также попытается обработать каталоги (если они есть); вы уже знаете что делать исправить.
Источник
Извлечение имени файла без пути и расширения в bash [дубликат]
этот вопрос уже есть ответ здесь:
данные имена файлов, как эти:
Я надеюсь получить:
почему это не сработает?
Как правильно это сделать?
9 ответов
вам не нужно вызывать внешний
на имени команда имеет два разных вызова; в одном вы указываете только путь, в этом случае он дает вам последний компонент, а в другом вы также даете суффикс, который он удалит. Таким образом, вы можете упростить свой пример кода, используя второй вызов basename. Кроме того, будьте осторожны, чтобы правильно цитировать вещи:
комбинация basename и cut отлично работает, даже в случае двойного окончания, такого как .tar.gz :
было бы интересно, если это решение требует меньше арифметической мощности, чем расширение параметра Bash.
чисто bash , нет basename , нет переменной жонглирование. Установите строку и echo :
Примечание: bash extglob опция должна быть «on», (on Ubuntu это» on » по умолчанию), если это не так, сделайте:
- $
$s. - // замените каждый экземпляр узор.
- +( матч один или несколько на список шаблон в скобках.
- *\/ все матчи до / . (1-й образец)
- | или. (разделитель шаблонов.)
- .* соответствует что-нибудь после . . (2-й образец)
- ) конец список шаблон.
- > параметр расширения, поскольку нет / (который предшествует замене строки), совпадающие шаблоны удаляются.
соответствующей man bash справочная информация:
мне это было нужно, так же, как спросили bongbang и w4etwetewtwet.
вот еще один (более сложный) способ получить имя файла или расширение, сначала используйте rev команда инвертировать путь к файлу, вырезать из первого . а затем снова инвертируйте путь к файлу, например:
Если вы хотите играть хорошо с путями файлов Windows (под Cygwin), вы также можете попробовать следующее:
это будет учитывать разделители обратной косой черты при использовании BaSH в Windows.
просто альтернатива, которую я придумал, чтобы извлечь расширение, используя сообщения в этом потоке с моей собственной небольшой базой знаний, которая была мне более знакома.
Примечание: пожалуйста, посоветуйте мне использовать цитаты; это сработало для меня, но я мог бы пропустить что-то по их правильному использованию (я, вероятно, использую слишком много).
Источник
Linux bash имя файла без расширения
У меня есть следующий for цикл, чтобы индивидуально sort все текстовые файлы внутри папки (т.е. создание отсортированного выходного файла для каждого).
Это почти идеально, за исключением того, что в настоящее время он выводит файлы в формате:
. тогда как я хотел бы выводить файлы в формате:
Это потому, что $ переменная содержит имя файла, включая расширение. Я запускаю Cygwin поверх Windows. Я не уверен, как это будет вести себя в реальной среде Linux, но в Windows это смещение расширения делает файл недоступным для Windows Explorer.
Как я могу отделить имя файла от расширения, чтобы я мог добавить _sorted суффикс между ними, что позволяет мне легко различать исходную и отсортированную версии файлов, сохраняя при этом расширения файлов Windows без изменений?
Я смотрел на то, что могло бы быть возможным решения, но мне это кажется более оборудованы для решения более сложных задач. Что еще более важно, с моими текущими bash знаниями, они выходят далеко за пределы моей головы, поэтому я надеюсь, что есть более простое решение, которое применимо к моему скромному for циклу, или что кто-то может объяснить, как применить эти решения к моей ситуации.
Эти решения, на которые вы ссылаетесь, на самом деле довольно хороши. В некоторых ответах может отсутствовать объяснение, поэтому давайте разберемся, добавим еще, может быть.
указывает на то, что расширение известно заранее (примечание: POSIX-совместимые среды чувствительны к регистру, *.txt не будут совпадать FOO.TXT ). В таком случае
должен вернуть имя без расширения ( basename также удаляет путь к каталогу: /directory/path/filename → filename ; в вашем случае это не имеет значения, поскольку $file не содержит такого пути). Чтобы использовать этот инструмент в вашем коде, вам нужна подстановка команды, которая выглядит, как это в целом: $(some_command) . Подстановка команд принимает выходные данные some_command , обрабатывает их как строку и помещает их туда, где $(…) находится. Ваше конкретное перенаправление будет
Вложенные кавычки в порядке, потому что Bash достаточно умен, чтобы знать, что кавычки внутри $(…) объединены в пару.
Это можно улучшить. Note basename — это отдельный исполняемый файл, а не встроенная оболочка (в Bash run type basename , сравните с type cd ). Создание любого дополнительного процесса является дорогостоящим, требует ресурсов и времени. Порождение его в цикле обычно работает плохо. Поэтому вы должны использовать все, что предлагает вам оболочка, чтобы избежать лишних процессов. В этом случае решение:
Синтаксис объясняется ниже для более общего случая.
Если вы не знаете расширение:
- $ — $file , но самое короткое соответствие строк *. удаляется спереди;
- $ — $file , но самая длинная строка соответствия *. удаляется спереди; используйте его, чтобы получить только расширение;
- $ — $file , но соответствие самой короткой строки .* удаляется с конца; используйте это, чтобы получить все, кроме расширения;
- $ — $file , но с самой длинной строкой совпадение .* удаляется с конца;
Сопоставление с образцом похоже на глобус, а не на регулярное выражение. Это означает * , что подстановочный знак для нуля или более символов, ? это подстановочный знак для ровно одного символа ( ? хотя в нашем случае мы не нуждаемся ). Когда вы вызываете ls *.txt или for file in *.txt; используете тот же механизм сопоставления с образцом. Шаблон без подстановочных знаков допускается. Мы уже использовали $ где .txt шаблон.
Но будьте осторожны:
По этой причине может быть полезна следующая штуковина (но это не так, объяснение ниже):
Он работает, идентифицируя все, кроме extension ( $ ), а затем удаляет это из всей строки. Результаты таковы:
Обратите внимание, что . включен в этот раз. Вы можете получить неожиданные результаты, если $file содержите литерал * или ? ; но Windows (где расширения имеют значение) не разрешает эти символы в именах файлов в любом случае, поэтому вам может быть все равно. Однако […] или <…>, если имеется, может вызвать собственную схему сопоставления с образцом и сломать решение!
Ваше «улучшенное» перенаправление будет:
Он должен поддерживать имена файлов с расширением или без расширения, хотя, к сожалению, не с квадратными или фигурными скобками. Довольно обидно. Чтобы это исправить, вам нужно заключить в двойную кавычку внутреннюю переменную.
Действительно улучшено перенаправление:
Двойные кавычки $ не делают шаблон! Bash достаточно умен, чтобы разделять внутренние и внешние кавычки, потому что внутренние встроены во внешний $ <…>синтаксис. Я думаю, что это правильный путь .
Другое (несовершенное) решение, давайте проанализируем его по образовательным причинам:
Он заменяет первый . на _sorted. . Это будет хорошо работать, если у вас есть не более одной точки $file . Существует аналогичный синтаксис, $ который заменяет все точки. Насколько я знаю, нет варианта заменить только последнюю точку.
Тем не менее первоначальное решение для файлов с . надежным внешним видом. Решение для extensionless $file тривиально: $_sorted . Теперь все, что нам нужно, это способ разграничить два случая. Вот:
Он возвращает состояние выхода 0 (true) тогда и только тогда, когда содержимое $file переменной соответствует шаблону с правой стороны. Шаблон говорит: «есть точка после хотя бы одного символа» или, что то же самое, «есть точка, которой нет в начале». Суть в том, чтобы рассматривать скрытые файлы Linux (например .bashrc ) как без расширения, если где-то нет другой точки.
Обратите внимание, что нам нужно [[ здесь, а не [ . Первый более мощный, но, к сожалению, не переносимый ; последний является портативным, но слишком ограниченным для нас.
Логика теперь выглядит так:
После этого, $file1 содержит желаемое имя, поэтому ваше перенаправление должно быть
И весь фрагмент кода ( *.txt заменен на, * чтобы указать, что мы работаем с любым расширением или без расширения):
Это попыталось бы также обработать каталоги (если они есть); Вы уже знаете, что нужно сделать, чтобы это исправить.
Источник