Linux bash соединить строки

Обновлено: 03.07.2024

Работа со строками в bash осуществляется при помощи встроенных в оболочку команд.

Термины

  • Консольные окружения — интерфейсы, в которых работа выполняется в текстовом режиме.
  • Интерфейс — механизм взаимодействия пользователя с аппаратной частью компьютера.
  • Оператор — элемент, задающий законченное действие над каким-либо объектом операционной системы (файлом, папкой, текстовой строкой и т. д.).
  • Текстовые массивы данных — совокупность строк, записанных в переменную или файл.
  • Переменная — поименованная область памяти, позволяющая осуществлять запись и чтение данных, которые в нее записываются. Она может принимать любые значения: числовые, строковые и т. д.
  • Потоковый текстовый редактор — программа, поддерживающая потоковую обработку текстовой информации в консольном режиме.
  • Регулярные выражения — формальный язык поиска части кода или фрагмента текста (в том числе строки) для дальнейших манипуляций над найденными объектами.
  • Bash-скрипты — файл с набором инструкций для выполнения каких-либо манипуляций над строкой, текстом или другими объектами операционной системы.

Сравнение строковых переменных

Для выполнения операций сопоставления 2 строк (str1 и str2) в ОС на основе UNIX применяются операторы сравнения.

Основные операторы сравнения

  1. Равенство « = »: оператор возвращает значение «истина» («TRUE»), если количество символов в строке соответствует количеству во второй.
  2. Сравнение строк на эквивалентность « == »: возвращается «TRUE», если первая строка эквивалентна второй ( дом == дом ).
  3. Неравенство «str1 != str2»: «TRUE», если одна строковая переменная не равна другой по количеству символов.
  4. Неэквивалентность «str1 !== str2»: «TRUE», если одна строковая переменная не равна другой по смысловому значению ( дерево !== огонь ).
  5. Первая строка больше второй «str1 > str2»: «TRUE», когда str1 больше str2 по алфавитному порядку. Например, « дерево > огонь » , поскольку литера «д» находится ближе к алфавитному ряду, чем «о».
  6. Первая строка меньше второй «str1 < str2»: «TRUE», когда str1 меньше str2 по алфавитному порядку. Например, « огонь < дерево », поскольку «о» находится дальше к началу алфавитного ряда, чем «д».
  7. Длина строки равна 0 « -z str2»: при выполнении этого условия возвращается «TRUE».
  8. Длина строки отлична от нулевого значения « -n str2»: «TRUE», если условие выполняется.

Пример скрипта для сравнения двух строковых переменных

Строки в bash - скрипт

Создание тестового файла

Обработка строк не является единственной особенностью консольных окружений Ubuntu. В них можно обрабатывать текстовые массивы данных.

  1. Для практического изучения команд, с помощью которых выполняется работа с текстом в интерпретаторе bash, необходимо создать текстовый файл txt .
  2. После этого нужно наполнить его произвольным текстом, разделив его на строки. Новая строка не должна сливаться с другими элементами.
  3. Далее нужно перейти в директорию, в которой находится файл, и запустить терминал с помощью сочетания клавиш — Ctrl+Alt+T.

Основы работы с grep

Поиск строки в файле операционной системы Linux Ubuntu осуществляется посредством специальной утилиты — grep . Она позволяет также отфильтровать вывод информации в консоли. Например, вывести все ошибки из log-файла утилиты ps или найти PID определенного процесса в ее отчете.

Команда grep работает с шаблонами и регулярными выражениями. Кроме того, она применяется с другими командами интерпретатора bash.

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

Для работы с утилитой grep необходимо придерживаться определенного синтаксиса

  1. grep [options] pattern [file_name1 file_name2 file_nameN] (где «options» — дополнительные параметры для указания настроек поиска и вывода результата; «pattern» — шаблон, представляющий строку поиска или регулярное выражение, по которым будет осуществляться поиск; «file_name1 file_name2 file_nameN» — имя одного или нескольких файлов, в которых производится поиск).
  2. instruction | grep [options] pattern (где «instruction» — команда интерпретатора bash, «options» — дополнительные параметры для указания настроек поиска и вывода результата, «pattern» — шаблон, представляющий строку поиска или регулярное выражение, по которым будет производиться поиск).

Строки в bash - синтаксис

Основные опции

Практическое применение grep

Поиск подстроки в строке

Строки в bash - grep

В окне терминала выводятся все строки, содержащие подстроку. Найденные совпадения подсвечиваются другим цветом.

  • С учетом регистра:
  • Без учета регистра:

Вывод нескольких строк

  • Строка с вхождением и две после нее:
  • Строка с вхождением и три до нее:
  • Строка, содержащая вхождение, и одну до и после нее:

Чтение строки из файла с использованием регулярных выражений

Регулярные выражения расширяют возможности поиска и позволяют выполнить разбор строки на отдельные элементы. Они активируются при помощи ключа -e.

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

Если воспользоваться числовыми интервалами, то можно вывести все строки, в которых встречаются числа:

Рекурсивный режим поиска

  • Чтобы найти строку или слово в нескольких файлах, расположенных в одной папке, нужно использовать рекурсивный режим поиска:
  • Если нет необходимости выводить имена файлов, содержащих искомую строку, то можно воспользоваться ключом-параметром деактивации отображения имен:

Точное вхождение

При поиске союза «и» grep будет выводить все строки, в которых он содержится. Чтобы этого избежать, требуется использовать специальный ключ « w »:

Поиск нескольких слов

Утилита «w» позволяет искать не только одно слово, но и несколько одновременно

Количество строк в файле

При помощи grep можно определить число вхождений строки или подстроки в текстовом файле и вывести ее номер.

Строки в bash - grep

  • Число вхождений:
  • Номера строк с совпадениями:

Инверсия

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

Вывод только имени файла

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

Использование sed

Потоковый текстовый редактор « sed » встроен в bash Linux Ubuntu. Он использует построчное чтение, а также позволяет выполнить фильтрацию и преобразование текста.

Синтаксис

Для работы с потоковым текстовым редактором sed используется следующий синтаксис:

sed [options] instructions [file_name] (где «options» — ключи-опции для указания метода обработки текста, «instructions» — команда, совершаемая над найденным фрагментом текста, «file_name» — имя файла, над которым совершаются действия).

Строки в bash - sed help

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

Распространенные конструкции с sed

Замена слова

Например, если требуется заменить строку в файле или слово с «команды» на «инструкции». Для этого нужно воспользоваться следующими конструкциями:

Редактирование файла

Чтобы записать строку в файл, нужно указать параметр замены одной строки на другую, воспользовавшись ключом — -i :

После выполнения команды произойдет замена слова «команды» на «инструкции» с последующим сохранением файла.

Удаление строк из файла

  • Удалить первую строку из файла:
  • Удалить строку из файла, содержащую слово«окне»:

Нумерация строк

Строки в файле будут пронумерованы следующим образом: первая строка — 1, вторая — 2 и т. д.

Строки в bash - нумерация строк

Следует обратить внимание, что нумерация начинается не с «0», как в языках программирования.

Удаление всех чисел из текста

Замена символов

Чтобы заменить набор символов, нужно воспользоваться инструкцией, содержащей команду « y »:

Обработка указанной строки

Утилита производит манипуляции не только с текстом, но и со строкой, указанной в правиле шаблона (3 строка):

Работа с диапазоном строк

Для выполнения замены только в 3 и 4 строках нужно использовать конструкцию:

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

В результате получаю ответ вида:

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

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

P.S. Строки переписал под тестовые, на деле использую нормальный адрес, но проблема даже с этими строками сохраняется.


48 1 1 золотой знак 1 1 серебряный знак 8 8 бронзовых знаков Я не знаю что это за чушь, но костыль найден. В конец каждой строки добавить знак ";" и все будет хорошо. Если у кого будет такая же проблема, попробуйте, может и вам поможет. Раньше с подобным не сталкивался. Более того, на локальной машине и на ideone код работает верно. Но если Вы нашли решение, пожалуйста, оставьте его в виде ответа, так будет проще людям, которые обратятся с подобной проблемой. Да, похоже проблема в том что все делалось на винде, через ide netbeans, а в качестве терминала использовался cygwin. Ide я написал тоже, так как скрипт был записан в sh файле, и только потом запущен через консоль на виртуалке с линуксом. Soon, хорошо, ответ постараюсь оформить по понятнее, может ещё у кого будут такие проблемы (сам больше часа на поиск решения потратил, пока не заметил что можно принудительно завершить строку символом точки с запятой). Спасибо всем кто прочитал и попробовал решить и разобраться в проблеме.

Попробуйте сделать так

UPD

Воссоздал ситуацию. Такое поведение возникает если скрипт записан следующим образом:

Но для того, чтобы его так записать, надо еще постараться.


Проблема у ТС не в тексте скрипта, там все правильно (копипаста в Linux работает).

Для решения проблемы нужно каждую логическую строку закончить символом точки с запятой ';'.
Прочитав комментарии понял что проблема кроется в одном или сразу всех далее следующих факторах.
Баг появляется если работать в windows, писать скрипт в файле, через ide, в данном случае netbeans, но возможно и фв других ide повторится, и запускать его через cygwin консоль, возможно так же повторится и в других подобных терминалах.
Пример рабочего скрипта.


48 1 1 золотой знак 1 1 серебряный знак 8 8 бронзовых знаков

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

Ответ 2

Bash также поддерживает оператор += как показано в этом коде:

Ответ 3

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

+= : Добавить к переменной

Синтаксис += может использоваться по-разному:

Добавить в строку var+=.

(Поскольку я скромен, я буду использовать только две переменные foo и a а затем повторно использовать их во всем ответе. ;-)

Используя синтаксис вопроса Stack Overflow,

Добавить к целому числу ((var+=. ))

переменная a является строкой, но также и целым числом

Добавить в массив var+=(. )

Наш a также является массивом только одного элемента.

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

Хм.. это не ошибка, а особенность. Чтобы предотвратить попытку разработки bash !" , Вы можете:

printf : перестроить переменную с помощью встроенной команды

printf команда printf предоставляет мощный способ рисования формата строки. Поскольку это встроенная функция Bash, существует возможность отправки отформатированной строки в переменную вместо печати на стандартный stdout :

В этом массиве семь строк. Таким образом, мы можем построить отформатированную строку, содержащую ровно семь позиционных аргументов:

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

Обратите внимание, что наш a все еще является массивом! Только первый элемент изменен!

В bash, когда вы обращаетесь к имени переменной без указания индекса, вы всегда обращаетесь только к первому элементу!

Таким образом, чтобы получить наш массив из семи полей, нам нужно только переустановить 1-й элемент:

Строка формата с одним аргументом и многими аргументами:

Использование синтаксиса вопроса:

Примечание: использование двойных кавычек может быть полезно для работы со строками, которые содержат spaces , tabulations и/или newlines

В оболочке POSIX вы не можете использовать bashisms, поэтому нет встроенного printf .

В принципе

Но вы могли бы просто сделать:

Отформатирован с использованием разветвленного printf

Если вы хотите использовать более сложные конструкции, вы должны использовать форк (новый дочерний процесс, который выполняет задание и возвращает результат через stdout ):

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

Но это не легко для вложения:

с обратными чертами вы должны избегать внутренних вилок с обратными слешами:

Ответ 4

Вы также можете сделать это:

Ответ 5

Это полезно, когда $blaohai приводит к ошибке переменной, не найденной. Или если в ваших строках есть пробелы или другие специальные символы. "$" правильно экранирует все, что вы вложили в него.

Ответ 6

Ответ 7

Как я решил проблему, просто

Если вы попытаетесь объединить строку с другой строкой, например,

то echo "$c" произведет

с дополнительным пространством.

не работает, как вы можете себе представить, но

Ответ 8

Ответ 9

Допустим, у нас есть две переменные и $ 1 установлен в "один":

Таблица ниже объясняет различные контексты, в которых мы можем комбинировать значения a и b для создания новой переменной c .

  • Заключение RHS присвоения в двойные кавычки, как правило, является хорошей практикой, хотя во многих случаях оно является необязательным.
  • += лучше с точки зрения производительности, если большая строка строится с небольшими приращениями, особенно в цикле
  • используйте <> вокруг имен переменных, чтобы устранить неоднозначность их расширения (как в строке 2 в таблице выше). Как видно из строк 3 и 4, нет необходимости в <> если переменная не конкатенируется со строкой, которая начинается с символа, который является допустимым первым символом в имени переменной оболочки, то есть является алфавитом или подчеркиванием.

Ответ 10

Если вы хотите добавить что-то вроде подчеркивания, используйте escape (\)

Это не работает:

Это отлично работает:

Ответ 11

Еще один подход.

Ответ 12

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

Этот последний оператор напечатает "OpenSystems" (без кавычек).

Это пример Bash script:

Ответ 13

Даже если теперь разрешен оператор + =, он был введен в Bash 3.1 в 2004 году.

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

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

Ответ 14

Самый простой способ с кавычками:

Ответ 15

Я предпочитаю использовать фигурные скобки $<> для расширения переменной в строке:

Скользящие скобки будут соответствовать непрерывному использованию строки:

В противном случае использование foo = "$fooWorld" не будет работать.

Ответ 16

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

С одним пробелом между:

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

Ответ 17

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

Плюс посмотрите другой ответ о + =

Ответ 18

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

Выведет "daniel"san , а не danielsan , как вы могли бы захотеть. В этом случае вы должны сделать следующее:

Ответ 19

Если это ваш пример добавления " World" в исходную строку, это может быть:

Ответ 20

Ответ 21

Вот как вы объединяете две строки.

Ответ 22

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

(ПРИМЕЧАНИЕ: date на macOS не предлагает наносекунды, поэтому это должно быть сделано в Linux.)

Ошибки показывают, что мой Bash дошел до 335.54432 МБ, прежде чем он разбился. Вы можете изменить код из удвоения данных для добавления константы, чтобы получить более гранулированный график и точку отказа. Но я думаю, что это должно дать вам достаточно информации, чтобы решить, заботитесь ли вы. Лично, ниже 100 Мб, я этого не делаю. Ваш пробег может отличаться.

Ответ 23

Я хотел построить строку из списка. Не смог найти ответ на этот вопрос, поэтому я разместил его здесь. Вот что я сделал:

и тогда я получаю следующий вывод:

Ответ 24

Обратите внимание, что это не сработает

поскольку он, кажется, отбрасывает $foo и оставляет вас с:

но это будет работать:

и вы получите правильный вывод:

Ответ 25

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

Ответ 26

Я делаю это так, когда это удобно: используйте встроенную команду!

Ответ 27

Ответ 28

Несмотря на специальный оператор += для конкатенации, существует более простой способ:

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

Ответ 29

Я вроде как быстро выполню.

Еще один способ кожи кошки. На этот раз с функциями: D

Ответ 30

Я еще не знаю о PHP, но это работает в Linux Bash. Если вы не хотите влиять на переменную, вы можете попробовать следующее:

Вы можете поместить другую переменную вместо "Hello" или "!". Вы также можете конкатенировать больше строк.

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

Bash также поддерживает оператор += , как показано в этом коде:

Баш первый

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

+= : добавить к переменной

Синтаксис += может использоваться по-разному:

Добавить к строке var+=.

(Поскольку я скромен, я буду использовать только две переменные foo и a , а затем повторно использовать их во всем ответе. ;-)

Используя синтаксис Stack Overflow question,

Добавить к целому числу ((var+=. ))

переменная a является строкой, но также и целым числом

Добавить в массив var+=(. )

Наше a также является массивом только одного элемента.

Обратите внимание, что между скобками есть разделенный пробелами массив. Если вы хотите сохранить строку, содержащую пробелы в вашем массиве, вы должны заключить их:

Хм .. это не ошибка, а особенность . Чтобы bash не пытался разработать !" , вы можете:

printf : перестроить переменную с помощью команды builtin

Команда printf builtin предоставляет мощный способ рисования формата строки. Поскольку это Bash встроенный, существует возможность отправки отформатированной строки в переменную вместо печати на stdout :

В этом массиве семь строк Таким образом, мы можем построить отформатированную строку, содержащую ровно семь позиционных аргументов:

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

Обратите внимание, что наше a все еще является массивом! Только первый элемент изменен!

В bash, когда вы обращаетесь к имени переменной без указания индекса, вы всегда обращаетесь только к первому элементу!

Таким образом, чтобы получить наш массив из семи полей, нам нужно только переустановить 1-й элемент:

Строка формата с одним аргументом и многими аргументами:

Использование синтаксиса Stack Overflow question:

Примечание: использование двойные кавычки может быть полезно для манипулирования строками, которые содержат spaces , tabulations и/или newlines

Shell сейчас

В POSIX Shell вы не можете использовать bashisms, поэтому нет встроенный printf .

В принципе

Но вы могли бы просто сделать:

Отформатирован с использованием forked printf

Если вы хотите использовать более сложные конструкции, вы должны использовать fork (новый дочерний процесс, который выполняет задание и возвращает результат через stdout ):

Исторически, вы могли использовать backticks для получения результата fork:

Но это нелегко для nesting:

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

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