Извлечь имя файла из файла

Обновлено: 04.07.2024

у меня есть список файлов, хранящийся в .log в следующий синтаксис:

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

чтобы извлечь имя файла без расширения, используйте boost::filesystem:: path:: stem вместо уродливого std:: string:: find_last_of(".")

если вы хотите безопасный способ (т. е. переносимый между платформами и не поставив предположений по пути), я бы рекомендовал использовать boost::filesystem .

это выглядело бы как-то так:

затем вы можете извлечь различные данные из этого пути. вот документация объекта path.

кстати: также помните, что для того, чтобы использовать путь, как

вам нужно бежать \ в строке дословно:

или использовать / вместо:

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

вы должны будете прочитать ваши имена файлов из файла в std::string . Вы можете использовать оператор извлечения строки std::ostream . После того, как у вас есть имя файла в std::string можно использовать std::string::find_last_of метод поиска последнего разделителя.

что-то вроде этого:

  1. читать std::string из входного потока ( std::ifstream ), каждый экземпляр будет полный путь
  2. сделать find_last_of на строку \
  3. извлеките подстроку из этой позиции до конца, теперь это даст вам имя файла
  4. сделать find_last_of на . , и подстрока с обеих сторон даст вам имя + расширение.

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

а затем замените косую черту на предпочтительную косую черту для ОС. Полезно, если он постоянно развертывается между Linux/Windows.

для linux или unix машин, ОС имеет две функции, связанные с пути и имена файлов. используйте man 3 basename, чтобы получить дополнительную информацию об этих функциях. Преимущество использования системной функциональности заключается в том, что вам не нужно устанавливать boost или писать свои собственные функции.

пример кода из man-страницы:

из-за неконстантного типа аргумента функции basename() это немного не прямолинейно используя это внутри кода C++. Вот простой пример из моей базы кода:

использование new / delete не является хорошим стилем. Я мог бы положить его в try / catch блок на случай, если что-то произошло между двумя вызовами.

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Перегрузки

Возвращает имя и расширение файла из пути к файлу, представленного диапазоном символов только для чтения.

Возвращает имя файла и расширение указанной строки пути.

GetFileName(ReadOnlySpan<Char>)

Возвращает имя и расширение файла из пути к файлу, представленного диапазоном символов только для чтения.

Параметры

Диапазон только для чтения, содержащий путь, из которого нужно получить имя и расширение файла.

Возвращаемое значение

Символы, следующие за последним символом разделителя каталогов в пути path .

Комментарии

Возвращаемый диапазон только для чтения содержит символы пути, следующие за последним разделителем в path . Если последним символом в path является символ или разделитель каталога, метод возвращает значение ReadOnlySpan<T>.Empty . Если path не содержит символа разделителя, метод возвращает значение path .

См. также раздел

Применяется к

GetFileName(String)

Возвращает имя файла и расширение указанной строки пути.

Параметры

Строка пути, из которой нужно получить имя файла и расширение.

Возвращаемое значение

Символы, следующие за последним символом разделителя каталогов в пути path . Если последним символом параметра path является символ разделения тома или каталога, этот метод возвращает Empty. Если значением параметра path является null , метод возвращает null .

Исключения

Примеры

в следующем примере демонстрируется поведение GetFileName метода на настольной платформе на основе Windows.

Комментарии

Возвращаемое значение —, null Если путь к файлу — null .

Символы разделения, используемые для определения начала имени файла, — это DirectorySeparatorChar и AltDirectorySeparatorChar .

поскольку \ является допустимым именем файла в unix, GetFileName работа с платформами на базе unix не может правильно возвращать имя файла из пути на основе Windows, например C: \ mydir \ myfile. ext, но GetFileName выполняемые на платформах на основе Windows могут правильно возвращать имя файла из пути на основе unix, например /тмп/мифиле.екст, поэтому поведение GetFileName метода не является строго одинаковым на платформах на базе unix и Windows.


О человечество! Это прекрасно! Всем огромное спасибо, тему можно считать решённой!

правильно! больше, еще больше велосипедов!

расскажи-ка, чем basename не подошел?

закон топикстартера: из 64 предложеных решений будет скрупулёзно выбрано самое вот такое

Это очень юниксвейно, да, на каждый возможный случай — своя утилита. Вот за это я и ненавижу linux. На самом деле лучший вариант из предложенных. Не надо плодить сущности.


На самом деле, я не знаю, что правильнее выбрать, поэтому выбрал то, что мне проще понять. Попробую варианты с седом и бэйснеймом и решу.

Ле. Человек препологающий, что RoR транслируется в js, что-то считает.


т.е. мне действительно интересно

я бы набыдлокодил grep path file | xargs basename

Stil ★★★★★ ( 05.10.14 01:16:32 )
Последнее исправление: Stil 05.10.14 01:19:11 (всего исправлений: 1)

Ни разу не граммарнаци, но 3 ошибки в одном слове, даже для меня пребор. Марш учить уроки, сучка!

сомневаюсь, что он осилит ответить, потому вот:


\K [6] Keep the stuff left of the \K, don't include it in $&

Ты крут, спасибо


Это очень юниксвейно, да, на каждый возможный случай — своя утилита. Вот за это я и ненавижу linux.

а я ненавижу из-за таких как ты пионеров, которые велосипеды придумывают типа sed 's|.*/\([^/]*\)$|\1|'



А sed не отдельная утилита, а встроенная команда bash?
Подсказка: basename входит в coreutils, а sed - отдельный пакет.

Lavos ★★★★★ ( 05.10.14 08:38:31 )
Последнее исправление: Lavos 05.10.14 08:39:42 (всего исправлений: 1)


Это очень юниксвейно, да, на каждый возможный случай — своя утилита.

Извлекаем информацию из файлов в Linux

При работе в Linux мы часто сталкиваемся с чтением файлов конфигурации и других текстовых файлов, которые могут быть довольно объемными. В этой заметке мы рассмотрим, как выбрать из файлов, интересующую нас информацию.

Для извлечения информации из файлов мы воспользуемся возможностями команды cut

Извлекаем информацию из файлов конфигурации

Каждый файл конфигурации в Linux имеет свой определенный формат. Предположим, что нам мы работаем с файлом /etc/passwd . Это файл, в котором хранится информация обо всех пользовательских учетных записях в системе Linux.

Чтобы вывести файл на экран, выполним команду cat :

Команда cat Выводим файл

В результате мы получим в командной строке полное содержимое файла /etc/passwd Информация о каждом пользователе выводится на отдельной строке в следующем формате:

Теперь, предположим, что мы хотим получить только список имен всех пользователей из файла /etc/passwd , без какой-либо дополнительной информации. То есть нам нужно извлечь из каждой строки файла имя пользователя. Для этого мы воспользуемся возможностями команды cut (не путать с командой cat).

Мы будем использовать две опции команды cut

  • -d (или --delimiter=РАЗДЕЛИТЕЛЬ ) — задает разделитель при обработке файла (по умолчанию используется символ табуляции).
  • -f (или --fields=СПИСОК ) — задает номера полей, которые нужно извлечь.

Выводим избранные поля из файла

Выведем только имена пользователей из файла /etc/passwd

Команда cut Вырезаем часть файла

  • Мы использовали опцию -d: , чтобы указать в качестве разделителя символ двоеточия :
    Это значит, что каждая строка файла разделяется на поля (части) по символу двоеточия.
  • Опция -f1 используется, чтобы выбрать в каждой строке первое поле.

Теперь выведем имена пользователей и их домашние директории. Для этого в списке полей добавим через запятую поле номер 6 (в нем выводится путь до домашней директории пользователя).

Команда cut Извлекаем информацию из файлов кофигурации в Linux

Заключение

Команда cut обладает и другими возможностями по извлечению информации из файлов в командной строке Linux. Для просмотра справки по команде cut , выполните команду:

У меня есть список файлов, хранящихся в .log с таким синтаксисом:

Я хочу извлечь имя и расширение из этих файлов. Вы можете привести простой способ сделать это?

Чтобы извлечь имя файла без расширения, используйте boost :: filesystem :: path :: stem вместо уродливого std :: string :: find_last_of (".")

Для C ++ 17 :

Как предлагает @RoiDanto , для форматирования вывода std::out может заключать вывод в кавычки, например:

Вы можете преобразовать std::filesystem::path в std::string с помощью p.filename().string() , если вам это нужно, например:

Если вам нужен безопасный способ (т.е. переносимость между платформами и отсутствие допущений в пути), я бы рекомендовал использовать boost::filesystem .

Это выглядело бы как-то так:

Затем вы можете извлекать различные данные из этого пути. Вот документация по объекту пути.

BTW: Также помните, что для использования пути вроде

Вам нужно экранировать \ в строковом литерале:

Или используйте вместо этого / :

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

Вам нужно будет прочитать свои имена файлов из файла в std::string . Вы можете использовать оператор извлечения строки std::ostream . Если у вас есть имя файла в std::string , вы можете использовать метод std::string::find_last_of , чтобы найти последний разделитель.

Что-то вроде этого:

  1. Прочтите std::string из входного потока ( std::ifstream ), каждый прочитанный экземпляр будет полным путем
  2. Сделайте find_last_of на строке для \
  3. Извлеките подстроку из этой позиции до конца, теперь это даст вам имя файла
  4. Сделайте find_last_of вместо . , и подстрока с любой стороны даст вам имя + расширение.

Попробуйте следующий трюк, чтобы извлечь имя файла из пути без расширения в C ++ и без внешних библиотек в C ++:

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

А затем замените косую черту предпочтительной косой чертой для ОС. Полезно, если вы постоянно выполняете развертывание между Linux / Windows.

Для машин linux или unix в ОС есть две функции, касающиеся пути и имен файлов. используйте man 3 basename, чтобы получить больше информации об этих функциях. Преимущество использования функций, предоставляемых системой, заключается в том, что вам не нужно устанавливать boost или писать свои собственные функции.

Пример кода со страницы руководства:

Из-за неконстантного типа аргумента функции basename () использование этого внутри кода C ++ немного непросто. Вот простой пример из моей кодовой базы:

Использование new / delete - не лучший стиль. Я мог бы поместить его в блок try / catch на случай, если что-то произойдет между двумя вызовами.

Ответы Николая Меркина и Ючена Чжуна великолепны, но, тем не менее, из комментариев вы можете видеть, что они не совсем точны.

Неявное преобразование в std :: string при печати приведет к заключению имени файла в кавычки. Комментарии тоже неточные.

Читайте также: