Linux разбить строку по разделителю

Обновлено: 04.07.2024

теперь я хотел бы разделить строки ; разделитель так, что у меня есть:

мне не обязательно нужен ADDR1 и ADDR2 переменные. Если они являются элементами массива, это еще лучше.

было решение, включающее установку Internal_field_separator (МФС) в ; . Я не уверен, что произошло с этим ответом, как вы сбрасываете IFS по умолчанию?

кстати, когда я пробовал

я получил только первую строку при печати это в петле, без скобок вокруг $IN это работает.

вы можете установить внутренний разделитель полей (IFS) переменная, а затем пусть она разбирается в массив. Когда это происходит в команде, то задание IFS происходит только в среде этой единственной команды (to read ). Затем он анализирует входные данные в соответствии с IFS значение переменной в массив, который затем можно перебрать.

он будет анализировать одну строку элементов, разделенных ; , толкая его в массив. Материал для переработки вся $IN , каждый раз, когда одна строка ввода разделяется ; :

эта конструкция заменяет все вхождения ';' (первоначальный // означает глобальную замену) в строке IN С ' ' (один пробел), затем интерпретирует строку с разделителями пробелов как массив (это то, что делают окружающие круглые скобки).

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

есть некоторые общие gotchas:

  1. если исходная строка имеет пробелы, вам нужно будет использовать ИФС:
    • IFS=':'; arrIN=($IN); unset IFS;
  2. если исходная строка содержит пробелы и разделитель-новая строка, вы можете установить ИФС С:
    • IFS=$'\n'; arrIN=($IN); unset IFS;

Если вы не возражаете немедленно обработать их, мне нравится делать это:

вы можете использовать такой цикл для инициализации массива, но, вероятно, есть более простой способ сделать это. Надеюсь, это поможет.

совместимый ответа

к этому вопросу SO, уже есть много разных способов сделать это в Баш. Но у Баша их много!--27-->специальные функции, так называемый bashism это хорошо работает, но это не будет работать в любом другом shell.

в частности, массивы, ассоциативный массив и замена шаблона чисты bashisms и не может работать под другим снаряды.

на Debian GNU/Linux, есть стандартный раковина тире, но я знаю многих людей, которые хотели бы использовать КШ.

наконец, в очень маленькой ситуации есть специальный инструмент под названием busybox и со своим собственным интерпретатором оболочки (Ясень).

просил строка

образец строки в SO вопрос:

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

разделить строку на основе разделителя в Баш (версия >=4.2)

под чисто Баш, мы можем использовать массивы и ИФС:

использование этого синтаксиса в недавнем bash не изменяется $IFS для текущего сеанса, но только для текущей команды:

теперь строку var разбивается и сохраняется в массив (с именем fields ):

мы можем запросить переменное содержимое с помощью declare -p :

read - это quickiest способ сделать сплит, потому что нет вилки и никаких внешних ресурсов называется.

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

или отбросьте каждое поле после обработки (мне нравится это сдвиг подход):

или даже для простой распечатки (более короткий синтаксис):

разделить строку на основе разделителя в shell

но если вы напишете что-то полезное под многими оболочками, вы должны не использовать bashisms.

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

(отсутствие этого является основной причиной публикации моего ответа;)

этот маленький пример сценария хорошо работает под Баш, тире, КШ, busybox и и был протестирован под bash Mac-OS тоже:

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

пример:

вы можете, очевидно, поместить это в цикл и повторить параметр-f, чтобы вытащить каждое поле независимо.

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

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

Favorite

Добавить в избранное

Главное меню » Операционная система Linux » 9 полезных примеров команды Split в Linux

9 полезных примеров команды Split в Linux

К оманда split в Linux позволяет разбивать файлы на несколько файлов. Есть несколько способов настроить параметры для вашего приложения. Мы покажем вам несколько примеров команды split, которые помогут вам понять ее использование.

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

Мы советуем вам быстро взглянуть на команду wc, чтобы понять вывод примеров команды split.

Примеры команды Split в Linux

Синтаксис команды Split:

Давайте посмотрим, как использовать его для разделения файлов в Linux.

1. Разделите файлы на несколько файлов

Давайте разделим пример файла журнала:

Если вы используете команду ls, вы можете увидеть несколько новых файлов в вашем каталоге.

Вы можете использовать wc для быстрой проверки количества строк после разделения.

Помните, что ранее мы видели, что наш исходный файл содержал 17 170 строк. Таким образом, мы можем видеть, что наша программа создала как и ожидалось, 18 новых файлов. 17 из них заполнены 1000 строками в каждой, а последняя имеет оставшиеся 170 строк.

Вы можете увидеть, что происходит с вашей командой на дисплее:

2. Разделите файлы на несколько файлов с определенными номерами строк

Мы понимаем, что вам может не понравиться, что файлы разбиты на файлы по 1000 строк. Вы можете изменить это поведение с помощью опции -l.

Теперь вы можете указать, сколько строк вы хотите в каждом из новых файлов.

Как вы можете догадаться, теперь разделенные файлы имеют по 500 строк каждая, кроме последней.

Теперь у вас есть намного больше файлов, но с половиной строк в каждом.

3. Разделение файлов на n файлов

Опция -n делает разделение на указанное число частей или кусков. Вы можете назначить, сколько файлов вы хотите, добавив целочисленное значение после -n.

Теперь вы можете видеть, что есть 15 новых файлов.

4. Разделение файлов с пользовательским префиксом имени

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

Вот разделенные файлы с именами, начинающимися с данного префикса.

5. Разделите и укажите длину суффикса

Разделение имеет длину суффикса по умолчанию 2 [aa, ab и т. д.]. Это изменится автоматически при увеличении количества файлов, но если вы хотите изменить его вручную, это тоже возможно. Допустим, вы хотите, чтобы наши файлы были названы как-то вроде AndreyExSeparatedLogFiles.log_aaaab.

Как ты можешь это сделать? Опция -a позволяет нам указать длину суффикса.

И вот разделенные файлы:

6. Разделить с помощью числового суффикса заказа

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

Давайте сохраним длину суффикса из предыдущего примера, но изменим алфавитную организацию на числовую с помощью опции -d.

Так что теперь у вас будут разделенные файлы с числовыми значениями.

7. Добавьте шестнадцатеричные суффиксы для разделения файлов

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

Мы использовали опцию -x для создания шестнадцатеричного суффикса. Затем разделили наш файл на 50 кусков и дали суффиксу длину 6.

И вот результат вышеупомянутой команды:

8. Разделите файлы на несколько файлов определенного размера

Синтаксис может стать немного сложнее, так как мы продолжаем добавлять опции. Итак, мы объясним, как работает команда, прежде чем показывать пример.

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

Вот разделенные файлы:

Вы можете проверить результат с помощью команды wc.

9. Разбивка файлов на несколько с определенным размером файла

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

В выводе вы можете видеть, что первый разделенный файл имеет размер около 1 МБ, тогда как остальная часть файла находится во втором файле.

Бонусный совет: воссоединение разделенных файлов

Это не команда split, но она может быть полезна для новых пользователей.

Как видите, наш воссозданный файл имеет тот же размер, что и наш оригинал.

Наше форматирование (включая количество строк) сохраняется в созданном файле.

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

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Favorite

Добавить в избранное

Главное меню » Операционная система Linux » csplit: лучший способ разделения файла в Linux на основе его содержимого

csplit - лучший способ разделения файла в Linux на основе его содержимого

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

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

Мы управляем своими запланированными твитами, используя файлы YAML. Типичный файл твитов содержит несколько твитов, разделенных четырьмя тире:

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

Но как разбить файл на несколько частей на основе его содержимого? Вероятно, вы можете получить что-то убедительное, используя команду awk :

Однако, несмотря на относительную простоту, такое решение не очень надежное: например, мы не правильно закрыли различные выходные файлы, поэтому это может очень сильно превысить ограничение на открытые файлы. Или что, если мы забыли разделитель перед самым первым твитом файла? Конечно, все, что можно обработать и зафиксировать в сценарии AWK, за счет усложнения его работы. Но зачем беспокоиться об этом, когда у нас есть инструмент csplit для выполнения этой задачи?

Использование csplit для разделения файлов в Linux

csplit - лучший способ разделения файла в Linux на основе его содержимого

Инструмента csplit является кузеном инструмента split , который можно использовать для разбиения файла на куски фиксированного размера. Но csplit будет определять границы блоков на основе содержимого файла, а не использовать количество байтов.

В этой статье мы продемонстрируем использование команды csplit, а также объясним вывод этой команды.

Так, например, если мы хотим разбить файл твита на основе разделителя ---- , то могли бы написать:

Возможно, вы догадались, что инструмент csplit использовал регулярное выражение, предоставленное в командной строке, для идентификации разделителя. И каковы могут быть результаты и 10983 отображаемые на стандартном выходе? Ну, это размер в байтах каждого созданного фрагмента данных.

Подожди минуту! Откуда берутся те имена файлов xx00 и xx01 ? И зачем csplit разбивать файл на две части ? И почему первый кусок данных имеет длину ноль байтов ?

Ответ на первый вопрос прост: xxNN (или более формально xx%02d ) является стандартным форматом имени файла, используемым csplit . Но вы можете изменить это, используя параметры --suffix-format и --prefix . Например, мы могли бы изменить формат на что-то более значимое для наших нужд:

Префикс является обычной строкой, но суффикс является строкой формата, как та, которая используется в стандартной библиотеке C функцией printf . Большинство символов формата будут использоваться дословно, за исключением спецификаций преобразования, которые вводятся знаком процента ( % ) и заканчивается спецификатором преобразования (здесь d ). Между ними формат может также содержать различные флаги и опции. В нашем примере %03d спецификация преобразования означает:

  • отобразить номер фрагмента как десятичное целое ( d ),
  • в поле ширины трех символов ( 3 ),
  • в конце с левой стороны с нулями ( ).

Но это не касается других запросов, которые у нас были выше: так почему у нас есть только два куска, один из которых содержит нулевые байты? Возможно, вы уже нашли ответ на этот последний вопрос самостоятельно: наш файл данных начинается с ---- самой первой строки. Таким образом, csplit он считается разделителем, и поскольку перед этой строкой не было данных, он создал пустой первый кусок. Мы можем отключить создание файлов с нулевыми байтами с помощью опции --elide-empty-files :

Ок: больше нет пустых файлов. Но в некотором смысле это результат худший, так как csplit разделяет файл всего на один кусок. Мы едва можем назвать это «разделение» файла, не так ли?

Объяснение этого удивительного результата csplit вовсе не предполагает, что каждый файл должен быть разделен на основе того же разделителя. Фактически, csplit требуется предоставить каждый используемый разделитель. Даже если это несколько раз то же самое:

Мы поместили три (одинаковых) разделителя в командной строке. Итак, csplit определил конец первого фрагмента на основе первого разделителя. Это приводит к тому, что фрагмент длины с нулевым байтом будет удален. Второй фрагмент был разделен следующим совпадением строк. /----/ . Превращение в кусок на 170 байт. Наконец, третий фрагмент длиной 250 байтов был идентифицирован на основе третьего разделителя. Остальные данные, 10426 байт, были помещены в последний кусок.

Очевидно, что это было бы нецелесообразно, если бы нам пришлось предоставить столько разделителей в командной строке, сколько в файле данных кусков. Тем более, что это точное число обычно заранее неизвестно. К счастью, csplit имеет специальный шаблон, означающий «повторить предыдущий шаблон как можно больше раз». Несмотря на свой синтаксис, напоминающий звездный квантификатор в регулярном выражении, это ближе к концепции Kleene plus, поскольку он используется для повторения разделителя, который уже встречался один раз:

И на этот раз, наконец, мы разделили свою коллекцию на отдельные части. Однако есть ли в csplip какие-то другие «специальные» шаблоны? Ну, мы не знаем, можем ли мы назвать их «особенными».

Больше шаблонов csplit

Это приводит к интересному угловому случаю. Что будет добавлено, если количество повторений превысит количество фактических разделителей в файле данных? Давайте посмотрим на примере:

Интересно, что csplit не только сообщила об ошибке, но и удалила все файлы chunk, созданные во время процесса. Обратите особое внимание на нашу формулировку: она удалила их. Это означает, что файлы были созданы, а затем, csplit столкнувшись с ошибкой, удалила их. Другими словами, если у вас уже есть файл, имя которого выглядит как файл chunk, он будет удален:

В приведенном выше примере файл tweet.002.yaml , который мы создали вручную, был перезаписан, а затем удален csplit .

Вы можете изменить это поведение с помощью опции --keep-files . Как следует из названия, оно не будет удалять куски csplit, созданные после обнаружения ошибки:

Обратите внимание, что в этом случае, несмотря на ошибку, csplit не отбрасывает данные:

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

Пропуск данных в csplit

При использовании символа процента ( % ) в качестве разделителя регулярных выражений вместо косой черты ( / ) csplit будет пропускаться данные до (но не включая) первой строки, соответствующей регулярному выражению. Это может быть полезно при игнорировании некоторых записей, особенно в начале или в конце входного файла:

Использование смещений при расщеплении файлов с помощью csplit

При использовании регулярных выражений ( /…​/ или %…​% ) вы можете указать положительное ( +N ) или отрицательное ( -N ) смещение в конце шаблона, так чтобы csplit разделил файл на N строк после или до соответствующей строки. Помните, что во всех случаях шаблон указывает конец фрагмента:

Разделить по номеру строки

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

Прежде чем переключиться на YAML, мы использовали для хранения запланированных твитов в плоском файле.

В этом файле твит был сделан из двух строк. Один из них содержит необязательное повторение, а второй содержит текст твита, причем новые строки заменены на \n. Еще раз, что образец файла доступен в Интернете.

С этим форматом «фиксированного размера» тоже можно было использовать, csplit чтобы поместить каждый отдельный твит в свой собственный файл:

Приведенный выше пример кажется легко понятным, но здесь есть две подводные камни. Во- первых, 2 дано в качестве аргумента csplit является строка номер, не линия подсчета. Однако при использовании повторения, как мы сделали, после первого совпадения csplit будет использовать это число в качестве счетчика строк. Если это не ясно, мы позволим вам сравнить выходные данные трех следующих команд:

Мы упомянули о второй ловушке, несколько связанной с первой. Возможно, вы заметили пустую строку в самой верхней части файла tweets.txt ? Это приводит к тому фрагменту tweet.000.txt , который содержит только символ новой строки. К сожалению, это требовалось в этом примере из-за повторения: помните, что мне нужны две строки. Таким образом, 2 это обязательное условие перед повторением. Но это также означает, что первый фрагмент будет разбит, но не включает в себя вторую строку. Другими словами, первый фрагмент содержит одну строку. Все остальные будут содержать 2 строки. Возможно, вы могли бы поделиться своим мнением в разделе комментариев, но, по моему мнению, это был неудачный выбор дизайна.

Вы можете уменьшить эту проблему, перейдя непосредственно к первой непустой строке:

Чтение из stdin

Конечно, как и большинство инструментов командной строки, csplit можно считывать входные данные со своего стандартного ввода. В этом случае вы должны указать - в качестве входного имени файла:

И это все, что мы хотели показать вам сегодня. Надеюсь, в будущем вы будете использовать csplit для разделения файлов в Linux. Если вам понравилась эта статья и не забывайте делиться ею в своей любимой социальной сети!

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.


> Есть что-нибудь более компактное без boost?
Без boost.

А вообще, чем приведенное решение не компактно?

> strtok, можно один раз написать функцию и использовать ее

Точно . я помню, что что-то такое в Си уже есть.

> А вообще, чем приведенное решение не компактно?

Через <string> - да, некомпактно. Хочется 2-3 строчек кода.

> QString Class Reference

Этот стиль программирования мне напоминает старый-добрый Borland Delphi.
Всё лаконично и аккуратно.


>Нашел два хороших способа:

По существу: если уж так хочется извращаться на крестах, то

> Мне кажется, тебе стоит вернуться обратно к похапе.

Когда я начинал программировать, похапэ вроде как и не существовало.


Если коротко и по делу: я раньше (в студенческое время) писал такой же быдлокод, как и у тебя.

Одна строчка кода:

Какая разница что там внутри, покуда оно работает нормально?


Вот порт реализации из Qt:

> strtok, можно один раз написать функцию и использовать ее

Хм-хм. А после вызова этой функции нужно долбить токены, пока те не закончатся? Получается, что strtok - не thread-safe?


>уровень призеров международных олимпиад по информатике и математике

Если коротко и по делу: я раньше (в студенческое время) писал такой же быдлокод, как и у тебя.

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

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

Но ты можешь продолжать и дальше гордиться тем, что учился со светилами Редмонда и писать свой кривой падучий крестовый быдлокод - каждому свое.

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