Извлечь имя файла из файла
Обновлено: 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 метод поиска последнего разделителя.
что-то вроде этого:
- читать std::string из входного потока ( std::ifstream ), каждый экземпляр будет полный путь
- сделать find_last_of на строку \
- извлеките подстроку из этой позиции до конца, теперь это даст вам имя файла
- сделать 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:39:42 (всего исправлений: 1)
Это очень юниксвейно, да, на каждый возможный случай — своя утилита.
При работе в Linux мы часто сталкиваемся с чтением файлов конфигурации и других текстовых файлов, которые могут быть довольно объемными. В этой заметке мы рассмотрим, как выбрать из файлов, интересующую нас информацию.
Для извлечения информации из файлов мы воспользуемся возможностями команды cut
Извлекаем информацию из файлов конфигурации
Каждый файл конфигурации в Linux имеет свой определенный формат. Предположим, что нам мы работаем с файлом /etc/passwd . Это файл, в котором хранится информация обо всех пользовательских учетных записях в системе Linux.
Чтобы вывести файл на экран, выполним команду cat :
В результате мы получим в командной строке полное содержимое файла /etc/passwd Информация о каждом пользователе выводится на отдельной строке в следующем формате:
Теперь, предположим, что мы хотим получить только список имен всех пользователей из файла /etc/passwd , без какой-либо дополнительной информации. То есть нам нужно извлечь из каждой строки файла имя пользователя. Для этого мы воспользуемся возможностями команды cut (не путать с командой cat).
Мы будем использовать две опции команды cut
- -d (или --delimiter=РАЗДЕЛИТЕЛЬ ) — задает разделитель при обработке файла (по умолчанию используется символ табуляции).
- -f (или --fields=СПИСОК ) — задает номера полей, которые нужно извлечь.
Выводим избранные поля из файла
Выведем только имена пользователей из файла /etc/passwd
- Мы использовали опцию -d: , чтобы указать в качестве разделителя символ двоеточия :
Это значит, что каждая строка файла разделяется на поля (части) по символу двоеточия. - Опция -f1 используется, чтобы выбрать в каждой строке первое поле.
Теперь выведем имена пользователей и их домашние директории. Для этого в списке полей добавим через запятую поле номер 6 (в нем выводится путь до домашней директории пользователя).
Заключение
Команда 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 , чтобы найти последний разделитель.
Что-то вроде этого:
- Прочтите std::string из входного потока ( std::ifstream ), каждый прочитанный экземпляр будет полным путем
- Сделайте find_last_of на строке для \
- Извлеките подстроку из этой позиции до конца, теперь это даст вам имя файла
- Сделайте find_last_of вместо . , и подстрока с любой стороны даст вам имя + расширение.
Попробуйте следующий трюк, чтобы извлечь имя файла из пути без расширения в C ++ и без внешних библиотек в C ++:
Я также использую этот фрагмент, чтобы определить подходящий символ косой черты:
А затем замените косую черту предпочтительной косой чертой для ОС. Полезно, если вы постоянно выполняете развертывание между Linux / Windows.
Для машин linux или unix в ОС есть две функции, касающиеся пути и имен файлов. используйте man 3 basename, чтобы получить больше информации об этих функциях. Преимущество использования функций, предоставляемых системой, заключается в том, что вам не нужно устанавливать boost или писать свои собственные функции.
Пример кода со страницы руководства:
Из-за неконстантного типа аргумента функции basename () использование этого внутри кода C ++ немного непросто. Вот простой пример из моей кодовой базы:
Использование new / delete - не лучший стиль. Я мог бы поместить его в блок try / catch на случай, если что-то произойдет между двумя вызовами.
Ответы Николая Меркина и Ючена Чжуна великолепны, но, тем не менее, из комментариев вы можете видеть, что они не совсем точны.
Неявное преобразование в std :: string при печати приведет к заключению имени файла в кавычки. Комментарии тоже неточные.
Читайте также: