Linux bash имя файла без расширения

Показать имена всех файлов в директории Bash Script

Введение

Перед тем как читать эту статью убедитесь, что вы знакомы с содержанием статьи «Основы Bash»

Показать имена всех файлов в директории

#!/bin/bash for file in ./**; do echo » $ » done

Показать файлы с определёныым расширением

Если нужны только файлы с расширением .jpg

#!/bin/bash for file in ./**.jpg; do echo » $ » done

Получить имя файла без расширения

Если нужно только имя файла без расширения

#!/bin/bash for file in ./**.jpg; do filename= » $ » echo $filename done

Получить только расширение файла

Если нужно только расширение

#!/bin/bash for file in ./**.jpg; do extension=»$» echo $EXT ension done

Преобразовать изображения в формат .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= » $ » newfile= $filename «.webp» cwebp -q 60 $file -o $newfile done

Добавить к названиям файлов суффикс

Если нужно сохранить расширение файла, а к оригинальному названию добавить какое-то слово или символ. А сделать это со всеми файлами данного типа в директории

Например в директории есть файлы 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= » $ » filename= » $ » temp= $filename $POSTFIX mv $file $$EXT done

А теперь скрипт, который делает и то и другое, а перед тем как делать проверяет нет ли уже такого файла

Источник

Получить имя файла без расширения в Bash

у меня есть следующие for цикл индивидуально sort все текстовые файлы внутри папки (т. е. создание отсортированного выходного файла для каждого).

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

. тогда как хотелось бы выводить файлы в формате:

это так $ переменная содержит имя файла с расширением. Я запускаю Cygwin на вершине Windows. Я не уверен, как это будет вести себя в истинной среде Linux, но в Windows это смещение расширения делает файл недоступным для Проводника Windows.

как я могу отделить имя файла от расширения, так что я могу добавить _sorted суффикс между ними, что позволяет мне легко различать оригинальные и сортированные версии файлов, сохраняя при этом расширения файлов Windows нетронутыми?

Я смотрел на то, что может be возможно решения, но мне они кажутся более приспособленными для решения более сложных проблем. Что еще важнее, с моим нынешним bash знание, они идут над моей головой, так что я держу надежду, что есть более простое решение, которое относится к моей скромной for цикл, или же кто-то может объяснить, как применить эти решения к моей ситуации.

1 ответов

эти решения, на которые вы ссылаетесь, на самом деле довольно хороши. Некоторые ответы могут не иметь объяснения, поэтому давайте разберемся, возможно, добавим еще.

указывает, что расширение известно заранее (Примечание: POSIX-совместимые среды чувствительны к регистру, *.txt не соответствует FOO.TXT ). В таком случае

должен возвращать имя без расширения ( basename также удаляет путь к каталогу: /directory/path/filename → filename ; в вашем случае это не имеет значения, потому что $file не содержит такого пути). Для использования инструмента в коде необходима подстановка команд, которая выглядит примерно так: $(some_command) . Команда подстановки принимает вывод some_command , обрабатывает его как строку и помещает в $(…) есть. Ваше конкретное перенаправление будет

Читайте также:  Что будет если отключить windows reporting

вложенные кавычки здесь в порядке, потому что Bash достаточно умен, чтобы знать кавычки в $(…) парные вместе.

это можно улучшить. Примечание basename — это отдельный исполняемый файл, а не встроенная оболочка (в bash run type basename для всех type cd ). Нерест любой лишний процесс обходится дорого, требует ресурсов и времени. Нерест его в петле обычно выполняет плохо. Поэтому вы должны использовать все, что предлагает вам оболочка, чтобы избежать дополнительных процессов. В этом случае решение:

синтаксис описан ниже для более общего случай.

в случае, если вы не знаете расширение:

  • $ — $file , но самая короткая строка, соответствующая *. удаляется спереди;
  • $ — $file , но самая длинная строка, соответствующая *. удаляется спереди; используйте его, чтобы получить только расширение;
  • $ — $file , но самая короткая строка, соответствующая .* удаляется из конец; используйте его, чтобы получить все, кроме расширения;
  • $ — $file , но с самой длинной строкой, соответствующей .* удаляется с конца;

сопоставление шаблонов похоже на glob, а не на regex. Это значит * — подстановочный знак для нуля или более символов, ? — это замена одного персонажа (нам не нужны ? в вашем случае, хотя). Когда вы вызываете ls *.txt или for file in *.txt; вы используете тот же шаблон, соответствующий механизм. Узор без подстановочных знаков допускается. Мы уже использовали $ здесь .txt — это шаблон.

но будьте осторожны:

по этой причине следующая штуковина может быть полезным (но это не так, объяснение ниже):

он работает, идентифицируя все, кроме расширения ( $ ), затем удаляет это из всей строки. Результаты выглядят так:

Примечание. the . включен в это время. Вы можете получить неожиданные результаты, если $file содержит литерал * или ? ; но Windows (где расширения имеют значение) не дает эти символы в именах файлов в любом случае, так что вам может быть все равно. Однако […] или <…>, если присутствует, может вызвать их собственную схему сопоставления с образцом и сломать решение!

ваше» улучшенное » перенаправление будет:

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

действительно улучшенное перенаправление:

двойное цитирование делает $ не действовать как шаблон! Bash достаточно умен, чтобы различать внутренние и внешние кавычки, потому что внутренние встроены во внешнюю $ <…>синтаксис. я думаю, что это правильно путь.

еще одно (несовершенное) решение, давайте проанализируем его по образовательным причинам:

заменяет первый . с _sorted. . Он будет работать нормально, если у вас есть не более одной точки в $file . Похожий синтаксис $ , который заменяет все точки. Насколько я знаю, нет никакого варианта, чтобы заменить последние точка только.

все еще первоначальное решение для файлов с . выглядит надежной. Решение для без расширений $file тривиально: $_sorted . Теперь все, что нам нужно, это способ разделить два дела. Вот это:

возвращает статус выхода 0 (true) тогда и только тогда, когда содержимое $file переменная соответствует шаблону правой стороны. Шаблон говорит: «есть точка после хотя бы одного символа» или, что то же самое, «есть точка, которая не находится в начале». Дело в том, чтобы лечить скрытые файлы Linux (например, .bashrc ), а без расширений, если есть другое точка где-то.

Примечание нам нужно [[ здесь, а не [ . Первый более мощный, но, к сожалению,не портативный; последнее является портативным, но слишком ограниченным для нас.

логика теперь выглядит так:

после этого, $file1 содержит желаемое имя, поэтому перенаправление должно быть

и весь код ( *.txt заменить * , чтобы указать нам работа с любым расширением или без расширения):

это также попытается обработать каталоги (если они есть); вы уже знаете что делать исправить.

Источник

Извлечение имени файла без пути и расширения в bash [дубликат]

этот вопрос уже есть ответ здесь:

данные имена файлов, как эти:

Я надеюсь получить:

почему это не сработает?

Как правильно это сделать?

9 ответов

вам не нужно вызывать внешний

на имени команда имеет два разных вызова; в одном вы указываете только путь, в этом случае он дает вам последний компонент, а в другом вы также даете суффикс, который он удалит. Таким образом, вы можете упростить свой пример кода, используя второй вызов basename. Кроме того, будьте осторожны, чтобы правильно цитировать вещи:

комбинация basename и cut отлично работает, даже в случае двойного окончания, такого как .tar.gz :

было бы интересно, если это решение требует меньше арифметической мощности, чем расширение параметра Bash.

чисто bash , нет basename , нет переменной жонглирование. Установите строку и echo :

Примечание: bash extglob опция должна быть «on», (on Ubuntu это» on » по умолчанию), если это не так, сделайте:

  1. $$s.
  2. // замените каждый экземпляр узор.
  3. +( матч один или несколько на список шаблон в скобках.
  4. *\/ все матчи до / . (1-й образец)
  5. | или. (разделитель шаблонов.)
  6. .* соответствует что-нибудь после . . (2-й образец)
  7. ) конец список шаблон.
  8. > параметр расширения, поскольку нет / (который предшествует замене строки), совпадающие шаблоны удаляются.

соответствующей 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 заменен на, * чтобы указать, что мы работаем с любым расширением или без расширения):

Это попыталось бы также обработать каталоги (если они есть); Вы уже знаете, что нужно сделать, чтобы это исправить.

Источник

Читайте также:  Драйвера для видеокарты ati radeon hd 2600 pro для windows 10
Оцените статью