ls -1
перечисляет мои элементы так:
foo.png
bar.png
foobar.png
...
Я хочу, чтобы это перечислилось без .png
так:
foo
bar
foobar
...
(каталог содержит только .png
файлы)
Может кто-нибудь сказать мне, как использовать grep
в этом случае?
Цель: у меня есть текстовый файл, где перечислены все имена без расширения. Я хочу сделать скрипт, который сравнивает текстовый файл с папкой, чтобы увидеть, какой файл отсутствует.
.
в них. Хотя в соглашении говорится, что имена файлов.png
должны указываться в конце, нет причины, по которой у меня не может быть файла png с именемfoo.zip
ormy.picture.20160518
or justmypic
.ls
и передавать по конвейеру выходные данные,ls
иfind
, главным образом, из-за возможности использоватьnewline
символ `tab char в имени файла. Если имя файлаThe new art of working on .png\NEWLINE files and other formats
много, предлагаемое решение создаст проблемы.Ответы:
Вам нужна только оболочка для этой работы.
POSIXly:
С
zsh
:источник
printf
;echo ${f%.png}
будет достаточно.Команда
sed
удаляет (то есть заменяет пустую строку) любую строку,.png
найденную в конце имени файла.Символ
.
экранируется\.
так, что он интерпретируетсяsed
как буквальный.
символ, а не как регулярное выражение.
(что означает совпадение с любым символом).$
Является якорным концом-линии, так что не соответствует.png
в середине файла.источник
sed 's/\.[^.]*$//'
-1
не обязательно, так как здесь по умолчанию.-1
следует указать. Это только по умолчанию, когда труба включена, что является скрытым сюрпризом для некоторых. Таким образом, сделать это явно помогает пониманию. Я также делаю это в своих сценариях, чтобы знать, какой вывод я ожидаю..png
) перед символом новой строки вы удалите даже это,.png
а не только последнее. Лучше избегать передачи и разбора вывода ls, он часто оставляет за собой хорошо скрытые сюрпризы ... (несколько слов и ссылок больше в ответе).Если вы просто хотите использовать bash:
Вы должны тянуться
grep
при попытке найти совпадения, а не об удалении / замене того, чтоsed
более уместно:Как только вы решите, что вам нужно создать несколько подкаталогов для наведения порядка в ваших файлах PNG, вы можете легко изменить это на:
источник
find
Конвейер вsed
раствор может представить некоторые проблемы , если вы нашли файл с ключом (.png
) как часть имени и непосредственно перед символом новой строки. Лучше избегать передачи и анализа выходных данныхfind
илиls
, это часто оставляет скрытые сюрпризы ... (некоторые слова и ссылки больше в ответе).find
на что-то, какecho
в последнем примере. Непонятно, для каких целей ониfind
служат, и результаты зависят от структуры каталогов (то есть, если у вас есть каталогfiles.png
)Я бы пошел
basename
(при условии реализации GNU):источник
-z
(или--zero
) GNU для создания вывода, разделенного NUL (вместо символа новой строки).Другой очень похожий ответ (я удивлен, что этот конкретный вариант еще не появился):
-1
опцияls
, посколькуls
предполагается, что если стандартный вывод не является терминалом (в данном случае это канал).-n
вариантsed
означает «не печатать строку по умолчанию»/p
вариант в конце замещения означает '... и распечатать эту строку , если замена была сделана.Чистый эффект , который должен распечатать только те строки , которые заканчиваются
.png
, с.png
удалены. То есть это также способствует небольшому обобщению вопроса ОП, где каталог не содержит только.png
файлы.sed -n
Метод часто оказывается полезным в тех случаях , когда вы могли бы использовать Grep + СЭД.источник
.png
) перед символом перевода строки: в этом случае вы напечатаете эту часть без png, не стирая только последнюю часть. Часто предлагается избегать анализа (и передачи) результатов,ls
потому что проблемы могут быть скрыты именно там, где вы не думаете ...find
или - возможно, лучше - используйте более мощный язык, чемsh
управлять им (тот факт, чтоsh
можно делать все, не означает, что это лучший выбор в каждый случай). Оболочка предназначена для удобства использования в первую очередь.ls
, но это грядущие проблемы. Часто мы создаем сценарии, которые будем использовать позже, когда мы уже забудем их предел ... (это человек, это обычно). Я предложил вfind
пример (с-exec
и без трубы) , даже если я считаю лучший вариант (потому что чистая раковина) ответить на один cuonglm в твердый и POSIX - совместимым.locate
илиmake
на них.Для этого вы можете использовать только команды BASH (без каких-либо внешних инструментов).
Это полезно, когда у вас нет / usr / bin и хорошо работает с именами файлов, такими как this.is.image.png, и со всеми расширениями.
источник
Не безопасно разбирать
ls
или передавать по трубамfind
[ 1 , 2 ]Не безопасно анализировать (и передавать) выходные данные
ls
илиfind
, главным образом потому, что в именах файлов можно найти необычные символы, такие как символ новой строки , вкладка ... Здесь будет работать чистый цикл оболочки [ cuonglm ] .Даже
find
команда, не включенная в опцию,-exec
будет работать:Обновления / Заметки : Вы можете использовать,
find .
чтобы искать даже скрытые файлы илиfind ./*.png
получать только не скрытые. С нимfind *.png -exec ...
могут возникнуть проблемы, если в нем присутствовал файл с именем,.png
потому что find получит его в качестве опции. Вы можете добавить,-maxdepth 0
чтобы избежать спуска в каталогах, названных какDir_01.png
, илиfind ./*.png -prune -exec ...
когда maxdepth не разрешен (спасибо Стефану). Если вы хотите избежать перечисления этих каталогов, вы должны добавить опцию-type f
(которая также исключает другие типы нестандартных файлов). Посмотритеman
на более полную панораму обо всех доступных опциях, и не забудьте проверить, когда они совместимы с POSIX, для лучшей переносимости.Еще несколько слов
Например, может случиться так, что при копировании заголовка из документа и вставке в имя файла одна или несколько строк новой строки будут заканчиваться в самом имени файла. Мы можем быть настолько неудачливы, что заголовок может содержать даже ключ, который мы должны использовать непосредственно перед новой строкой:
Если вы хотите проверить, вы можете создать имена файлов, как это с помощью команд
Простое
/bin/ls *png
будет выводить?
вместо непечатных символовВо всех случаях , в которых вы будете трубы на выходе из
ls
илиfind
следующая команда не будет иметь никакого намека , чтобы понять , если нынешняя линия исходит от нового имени файла или если он следует символ новой строки символ в Прецедент имени файла . Противное имя действительно, но до сих пор правовые один.Цикл оболочки с параметром-расширением оболочки
${parameter%word}
, в обоих вариантах сprintf
илиecho
будет работать [ cuonglm ], [ Anthon1 ] .Со страницы руководства по расширению параметров оболочки [ 3 ]
источник
find
команды являются битовой переменной (например, если есть каталог с именемfiles.png
)bash 4.3.11
dash 0.5.7-4, zsh (при необходимости) 5.0.2. Не стесняйтесь читать этот пост, который добавляет что-то еще. Я согласен с примечанием о том, как обвязать выводfind
, для этого я прямо предложил-exec
, и я написал в заголовке.:-)
,ls
нет никакой проблемы, когда вывод передается по каналу или перенаправляется, но, как упоминалось в вики, он может работать не для всех. Большинство будет вставлять?
вместо специальных символов, только когда выходные данные отправляются на терминал. т.е.echo *.png | od -c
иls *.png | od -c
. Проблема с новой строкой - это не проблемаls
, это проблема с любой командой, которая не завершается нулем по обе стороны канала.printf "${f%.png}\n"
неправильно. Первый аргумент - это формат, вы не должны использовать переменные данные там. Может даже рассматриваться как уязвимость DoS (попробуйте, например, с%1000000000s.png
файлом).find ./*.png -prune -exec...
или у вас будут проблемы с именами файлов, начинающимися с-
(и файлами типа directory, обратите внимание, что они-maxdepth
не переносимы)разве этого было недостаточно?
или вообще это
удалит все расширения
источник
-1
не обязательно, так как здесь по умолчанию.ls
делает это в любом случае без этой опции, когда его вывод не является терминалом, как здесь.Используйте
rev
:rev
переворачивает все строки (строки); Вы режете все после первого "." и rev реверсирует остаток.Если вы хотите
grep
«Алма»:источник
-1
не обязательно, так как здесь по умолчанию.My.2016.Summer.Vacation.png
cut -f 2-
.png
новой строкой сразу после ... Рекомендуется избегать разбора,ls
потому что он любит хорошо скрывать сюрпризы ... :-)Если бы я знал, что в каталоге есть только файлы с расширением .png, я бы просто запустил:
ls | awk -F. '{print $1}'
Это вернет первое «поле» для всего, где есть имя файла .extension.
Пример:
источник
.
, какImage.1.png
и даже для имен с не хорошими именами , со специальными символами внутри. как символ новой строки , или тот , который вы будете использовать в качестве (вход) разделитель записей вawk
,RS
. Рекомендуется избегать разбораls
выходных данных, потому что он любит скрывать проблемы, которые возникнут, когда вы этого не ожидаете. Вы можете прочитать больше в этих ссылках 1 или 2 . Кстати, хорошая идея использовать awk ... Я привел несколько примеров в одном ответе..
в\.
внутриsed -e 's/\.png$//'
, но так будет ответ только что написал. :-( note2 вы можете попытаться использоватьawk
что-то вродеls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'
... но у вас всегда будет проблема, из-за которой awk не может знать, идет ли следующая строка или нет новой строки в имени файла. Я попытался сказать лучше в своем ответе .в соответствии с вашим комментарием «У меня есть текстовый файл, в котором перечислены все имена без расширения. Я хочу сделать PHP-скрипт, который сравнивает текстовый файл с папкой, чтобы увидеть, какой файл отсутствует»:
и наоборот:
источник
ls -l | sed 's/\.png$//'
Это самый точный метод, как подчеркивает @roaima. Без уцелевших
\.png
файлы с именемa_png.png
будут перечислены как:a_
.источник
ls -l
, как вы делаете, дает подробности файла, это не то, о чем спрашивал ОП.Простая строка оболочки (ksh, bash или zsh; не тире):
Простая функция (без расширения):
Или функция, которая удаляет любое данное расширение (png по умолчанию):
Использовать как:
Если выходные данные являются звездочкой
*
, файл с таким расширением не существует.источник
Вы можете попробовать следующую ленту awk, если у вашего суператора есть "." и так как все ваши файлы будут иметь name.png, вы напечатаете первый столбец:
ls | awk -F"." '{print $1}'
источник
Если у вас есть доступ к sed, это лучше, так как он удалит последнее расширение файла, независимо от того, что это (png, jpg, tiff и т. Д.)
источник
this.is.a.dotty.txt
. Попробуйs/\.[^.]*$//
вместо этого.