- Как разбить строку на слова, разделенные одним или несколькими пробелами в bash?
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
- Ответ 9
- Как разбить строку на разделителе в Bash?
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Совместимый ответ
- Запрашиваемая строка
- Разделить строку на основе разделителя в bash (версия> = 4.2)
- Обновление: недавно bash> = 4.4
- Разделить строку на основе разделителя в shell
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
- Ответ 9
- Ответ 10
- Ответ 11
- Ответ 12
- Обновление для Bash ≥4.4
- Ответ 13
- Ответ 14
- Ответ 15
- Ответ 16
- Ответ 17
- Ответ 18
- Ответ 19
- Ответ 20
- Ответ 21
- Ответ 22
- Ответ 23
- Ответ 24
- Ответ 25
- Ответ 26
- Ответ 27
- Ответ 28
- Ответ 29
- Ответ 30
- Centos
- Метод 1: Разделить строку с помощью команды чтения в Bash
- Способ 2: разделить строку с помощью команды trim в Bash
Как разбить строку на слова, разделенные одним или несколькими пробелами в bash?
Я понимаю, как это сделать в python, только с
но как я могу сделать то же самое в bash? действительно ли можно сделать это так просто?
ОТВЕТЫ
Ответ 1
Ответ 2
Это зависит от того, что вы подразумеваете под расколом. Если вы хотите перебирать слова в строке, которая находится в переменной, вы можете просто перебирать ее. Например, допустим, что переменная line равна this is a line . Затем вы можете сделать это:
for .. in $var разделяет $var , используя значения в $IFS , значение по умолчанию которого означает «разделенные пробелы и новые строки».
Если вы хотите читать строки от пользователя или файла, вы можете сделать что-то вроде:
Для чего-то еще, вам нужно быть более явным и более подробно определить свой вопрос.
Примечание. Отредактировано для удаления башизма, но я все еще сохранял cat $filename | . , потому что мне больше нравится перенаправление.
Ответ 3
Если вам требуется конкретное слово из строки, awk может оказаться полезным, например
Печатает второе разделенное пробел слово в $LINE. Вы также можете разделить на другие символы, например.
Ответ 4
дает результат, аналогичный результатам большинства ответов выше; без использования петель.
В вашем случае вы также упомянете ll= ,
так, (учитывая, что я не знаю много python и предполагаю, что вам нужно назначить вывод переменной),
должно быть достаточно (вспомните echo «$ll» вместо echo $ll )
Ответ 5
Ответ 6
$1, $2 и т.д. будут вашим 1-м и 2-м разделенными полями. используйте [email protected], чтобы получить все значения. Используйте $#, чтобы получить длину «полей».
Ответ 7
\ s → пробельный символ (пробел, табуляция, NL, FF, VT, CR). Во многих системы также действительны [: пробел:]
Ответ 8
Параметр -a read позволит вам разбить строку, считанную символами, содержащимися в $IFS .
Ответ 9
Если у вас уже есть строка текста в переменной $LINE, вы должны иметь возможность сказать
Источник
Как разбить строку на разделителе в Bash?
У меня есть эта строка, хранящаяся в переменной:
Теперь я хотел бы разделить строки на разделитель ; , чтобы у меня было:
Мне необязательно нужны переменные ADDR1 и ADDR2 . Если они являются элементами массива, которые еще лучше.
После предложений из нижеприведенных ответов я закончил следующее, что было после:
Было решение, связанное с установкой Internal_field_separator (IFS) на ; . Я не уверен, что случилось с этим ответом, как вы reset IFS вернулись к умолчанию?
RE: IFS solution, я пробовал это, и он работает, я сохраняю старый IFS , а затем восстанавливаю его:
Кстати, когда я пробовал
У меня появилась первая строка при печати в цикле, без скобок вокруг $IN она работает.
ОТВЕТЫ
Ответ 1
Вы можете установить переменную internal field separator (IFS), а затем разрешить ее анализировать в массив. Когда это происходит в команде, тогда назначение IFS происходит только в этой среде с одной командой (до read ). Затем он анализирует вход в соответствии с значением переменной IFS в массив, который затем мы можем перебрать.
Он проанализирует одну строку элементов, разделенных ; , нажав ее в массив. Материал для обработки всего $IN , каждый раз, когда одна строка ввода разделяется символом ; :
Ответ 2
Эта конструкция заменяет все вхождения ‘;’ (начальная // означает глобальную замену) в строке IN с помощью ‘ ‘ (одно пробел), а затем интерпретирует строку с разделителями пробела как массив (это что окружающие круглые скобки).
Синтаксис, используемый внутри фигурных скобок для замены каждого символа ‘;’ символом ‘ ‘ , называется Расширение параметров.
Есть некоторые распространенные ошибки:
- Если исходная строка содержит пробелы, вам нужно будет использовать IFS:
- IFS=’:’; arrIN=($IN); unset IFS;
- Если исходная строка содержит пробелы, а разделитель — это новая строка, вы можете установить IFS с помощью:
- IFS=$’\n’; arrIN=($IN); unset IFS;
Ответ 3
Если вы не возражаете обрабатывать их немедленно, мне нравится делать это:
Вы можете использовать этот тип цикла для инициализации массива, но, вероятно, это более простой способ сделать это. Надеюсь, что это поможет.
Ответ 4
Совместимый ответ
На этот вопрос SO уже есть много разных способов сделать это в bash. Но у bash есть много специальных функций, так называемый bashism, которые хорошо работают, но не работают ни в одном другом shell.
В частности, массивы, ассоциативные массивы и подстановки шаблонов — это чистые ошибки и могут не работать под другими оболочками.
В моем Debian GNU/Linux есть стандартная оболочка под названием dash, но я знаю многих людей, которые любят использовать ksh.
Наконец, в очень маленькой ситуации есть специальный инструмент под названием busybox с собственным интерпретатором оболочки (ash).
Запрашиваемая строка
Пример строки в вопросе SO:
Поскольку это может быть полезно с пробелами и поскольку пробелы могут изменить результат процедуры, я предпочитаю использовать эту строку-образец:
Разделить строку на основе разделителя в bash (версия> = 4.2)
Под чистым bash мы можем использовать массивы и IFS:
Использование этого синтаксиса в недавнем bash не меняет $IFS для текущего сеанса, а только для текущей команды:
Теперь строка var разделяется и сохраняется в массив (именованные fields ):
Мы могли бы запросить переменное содержимое с помощью declare -p :
read — самый быстрый способ выполнить разделение, потому что нет никаких вилок и не вызывается никаких внешних ресурсов.
Оттуда вы можете использовать синтаксис, который вы уже знаете, для обработки каждого поля:
или отбросить каждое поле после обработки (мне нравится этот подход смещения):
или даже для простой распечатки (более короткий синтаксис):
Обновление: недавно bash> = 4.4
Вы можете играть с mapfile :
Этот синтаксис сохраняет специальные символы, новые строки и пустые поля!
Если вам не нужны пустые поля, вы можете:
Но вы можете использовать поля через функцию:
(Примечание: \0 в конце строки формата бесполезны, в то время как вам нет дела до пустых полей в конце строки)
Будет что-то вроде:
Или Удалить новую строку, добавленную с помощью синтаксиса bash в функции:
Будет отображать тот же результат:
Разделить строку на основе разделителя в shell
Но если бы вы написать что — то полезное под многими оболочками, вы должны не использовать bashisms.
Существует синтаксис, используемый во многих оболочках, для разделения строки по первому или последнему вхождению подстроки:
(Отсутствие этого является основной причиной публикации моего ответа;)
# и % удаляют самую короткую подходящую строку и
## и %% удаляют самое длинное из возможных.
где # и ## означают слева (начало) строки, и
% и %% означают справа (конец) строки.
Этот небольшой пример сценария хорошо работает в bash, dash, ksh, busybox и также был протестирован в Mac-OS bash:
Ответ 5
Я видел пару ответов, ссылающихся на команду cut , но все они были удалены. Немного странно, что об этом никто не говорил, потому что я считаю это одной из наиболее полезных команд для этого типа вещей, особенно для разбора файлов журналов с разделителями.
В случае разделения этого конкретного примера на массив bash script tr , вероятно, более эффективен, но cut может быть использован и более эффективен, если вы хотите вытащить определенные поля из средний.
Пример:
Вы можете, очевидно, поместить это в цикл и перебрать параметр -f, чтобы вытащить каждое поле независимо.
Это становится более полезным, если у вас есть файл журнала с разделителями с такими строками:
cut очень удобно, чтобы иметь возможность cat этого файла и выбрать конкретное поле для дальнейшей обработки.
Ответ 6
Это сработало для меня:
Ответ 7
Как насчет этого подхода:
Ответ 8
Ответ 9
Это также работает:
Будьте осторожны, это решение не всегда правильно. Если вы передадите только «[email protected]», он назначит его как ADD1, так и ADD2.
Ответ 10
Я думаю, что AWK — лучшая и эффективная команда для решения вашей проблемы. AWK включен по умолчанию почти во все дистрибутивы Linux.
Конечно, вы можете сохранить каждый адрес электронной почты, переопределив поле печати awk.
Ответ 11
Другой подход к Darron answer, вот как я это делаю:
Ответ 12
В Bash, пуленепробиваемый способ, который будет работать, даже если ваша переменная содержит символы новой строки:
Трюк для этого заключается в использовании опции -d read (разделитель) с пустым разделителем, так что read вынужден читать все, что он кормил. И мы корнем read с точностью до содержимого переменной in , без конечной новой строки благодаря printf . Обратите внимание, что мы также помещаем разделитель в printf , чтобы гарантировать, что строка, переданная в read , имеет трейлинг-разделитель. Без него read обрезает потенциальные конечные пустые поля:
сохраняется оставшееся пустое поле.
Обновление для Bash ≥4.4
Так как Bash 4.4, встроенный mapfile (aka readarray ) поддерживает параметр -d для указания разделителя. Следовательно, другой канонический способ:
Ответ 13
Как насчет этого одного лайнера, если вы не используете массивы:
Ответ 14
Это должно работать везде:
(Обратите внимание, что этот метод стоит того, если вы новичок в Bash, и вам просто нужен простой и короткий трюк. Академический и «правильный» способ заключается в использовании IFS, как указано в других сообщениях.)
Ответ 15
Вот чистый 3-лайнер:
где IFS разграничивает слова на основе разделителя, а () используется для создания array. Затем [@] используется для возврата каждого элемента в виде отдельного слова.
Если после этого у вас есть какой-либо код, вам также необходимо восстановить $IFS , например. unset IFS .
Ответ 16
Без настройки IFS
Если у вас есть только один двоеточие, вы можете это сделать:
Ответ 17
Следующая функция Bash/zsh разделяет свой первый аргумент на разделителе, заданном вторым аргументом:
Этот вывод может, например, быть передан в другие команды. Пример:
По сравнению с другими полученными решениями, это имеет следующие преимущества:
IFS не переопределяется: из-за динамического охвата четных локальных переменных переопределение IFS по циклу заставляет новое значение протекать в вызовы функций, выполняемые внутри цикла.
Массивы не используются: чтение строки в массив с использованием read требует наличия флага -a в Bash и -a в zsh.
При желании функцию можно поместить в script следующим образом:
Ответ 18
вы можете применить awk для многих ситуаций
также вы можете использовать этот
Ответ 19
Существует простой и понятный способ:
Но вы должны использовать gnu xargs, BSD xargs can not support -d delim. Если вы используете яблочный mac, как я. Вы можете установить gnu xargs:
Ответ 20
Это самый простой способ сделать это.
Ответ 21
Здесь есть несколько интересных ответов (ошибочный вариант), но для чего-то аналогичного расколу на других языках — вот что я понял в исходном вопросе — я решил:
Теперь $ , $ и т.д., как и следовало ожидать. Используйте $ <#a[*]>для количества терминов. Или, конечно же, повторить:
Это работает в тех случаях, когда нет проблем, о которых можно было бы беспокоиться, что решило мою проблему, но может не решить вашу проблему. Пойдите с решением $IFS в этом случае.
Ответ 22
Система: Ubuntu 12.04.1
Ответ 23
Если нет места, почему бы не это?
Ответ 24
Две альтернативы bourne-ish, где не требуется bash массивы:
Случай 1: держите его красивым и простым: используйте NewLine в качестве разделителя записей. например.
Примечание: в этом первом случае подпроцесс не используется для поддержки манипулирования списком.
Идея: Может быть, стоит использовать NL внутри себя и только преобразовывать в другой RS при создании окончательного результата извне.
Случай 2: использование символа «;» как разделитель записей. например.
В обоих случаях суб-список может быть составлен в цикле, является постоянным после завершения цикла. Это полезно при манипулировании списками в памяти, вместо этого хранения списков в файлах.
Ответ 25
Объяснение: Простое назначение с помощью скобки() преобразует разделенный точкой с запятой список в массив, если у вас есть правильный IFS при этом. Стандартный цикл FOR обрабатывает отдельные элементы в этом массиве, как обычно. Обратите внимание, что список, указанный для переменной IN, должен быть «жестким», т.е. С одиночными тиками.
IFS необходимо сохранить и восстановить, так как Bash не относится к назначению так же, как и к команде. Альтернативное обходное решение состоит в том, чтобы обернуть назначение внутри функции и вызвать эту функцию с измененным IFS. В этом случае отдельное сохранение/восстановление IFS не требуется. Спасибо за «Bize» за указание на это.
Ответ 26
Помимо фантастических ответов, которые уже были предоставлены, если это просто вопрос распечатки данных, вы можете использовать awk :
Это устанавливает разделитель полей в ; , чтобы он мог проходить через поля с контуром for и печатать соответственно.
С другим вводом:
Ответ 27
Используйте встроенный set для загрузки массива [email protected] :
Затем начнем вечеринку:
Ответ 28
В оболочке Android большинство предложенных методов просто не работают:
Что такое работа:
где // означает глобальную замену.
Ответ 29
Почему этот подход для меня «лучший»?
Из-за двух причин:
- Вам не нужно скрывать разделитель;
- У вас не будет проблемы с пробелами. Значение будет правильно разделено в массиве!
Ответ 30
Однострочный разделитель строки, разделенной символом ‘;’ в массив:
Это только устанавливает IFS в подоболочку, поэтому вам не нужно беспокоиться о сохранении и восстановлении его значения.
Источник
Centos
Допустим, у вас есть длинная строка с несколькими словами, разделенными запятой или подчеркиванием. Вы хотите разбить эту строку и извлечь отдельные слова.
Вы можете разделить строки в bash, используя разделитель внутренних полей ( IFS ) и команду чтения, или вы можете использовать команду обрезки. Позвольте нам показать вам, как это сделать на примерах.
Метод 1: Разделить строку с помощью команды чтения в Bash
Вот наш пример сценария для разделения строки с помощью команды read:
Часть, которая разбивает строку, находится здесь:
IFS определяет разделитель, по которому вы хотите разбить строку. В нашем случае это точка с запятой. Это может быть что угодно: пробел, табуляция, запятая или даже алфавит.
IFS в команде read разделяет входные данные в разделителе. Команда read читает необработанный ввод (опция -r), поэтому интерпретирует обратную косую черту буквально, а не обрабатывает их как escape-символ. Опция -a с командой read сохраняет слово read в массиве.
Проще говоря, длинная строка разбивается на несколько слов, разделенных разделителем, и эти слова хранятся в массиве.
Теперь вы можете получить доступ к массиву, чтобы получить любое слово, которое вы хотите, или использовать цикл for в bash, чтобы напечатать все слова одно за другим, как мы делали в приведенном выше сценарии.
Вот вывод вышеприведенного скрипта:
Ubuntu
Linux Mint
Debian
Arch
Fedora
Способ 2: разделить строку с помощью команды trim в Bash
Это пример разделения строки bash с использованием команды trim (tr):
Источник