Linux bash соединить строки
Работа со строками в bash осуществляется при помощи встроенных в оболочку команд.
Термины
- Консольные окружения — интерфейсы, в которых работа выполняется в текстовом режиме.
- Интерфейс — механизм взаимодействия пользователя с аппаратной частью компьютера.
- Оператор — элемент, задающий законченное действие над каким-либо объектом операционной системы (файлом, папкой, текстовой строкой и т. д.).
- Текстовые массивы данных — совокупность строк, записанных в переменную или файл.
- Переменная — поименованная область памяти, позволяющая осуществлять запись и чтение данных, которые в нее записываются. Она может принимать любые значения: числовые, строковые и т. д.
- Потоковый текстовый редактор — программа, поддерживающая потоковую обработку текстовой информации в консольном режиме.
- Регулярные выражения — формальный язык поиска части кода или фрагмента текста (в том числе строки) для дальнейших манипуляций над найденными объектами.
- Bash-скрипты — файл с набором инструкций для выполнения каких-либо манипуляций над строкой, текстом или другими объектами операционной системы.
Сравнение строковых переменных
Для выполнения операций сопоставления 2 строк (str1 и str2) в ОС на основе UNIX применяются операторы сравнения.
Основные операторы сравнения
- Равенство « = »: оператор возвращает значение «истина» («TRUE»), если количество символов в строке соответствует количеству во второй.
- Сравнение строк на эквивалентность « == »: возвращается «TRUE», если первая строка эквивалентна второй ( дом == дом ).
- Неравенство «str1 != str2»: «TRUE», если одна строковая переменная не равна другой по количеству символов.
- Неэквивалентность «str1 !== str2»: «TRUE», если одна строковая переменная не равна другой по смысловому значению ( дерево !== огонь ).
- Первая строка больше второй «str1 > str2»: «TRUE», когда str1 больше str2 по алфавитному порядку. Например, « дерево > огонь » , поскольку литера «д» находится ближе к алфавитному ряду, чем «о».
- Первая строка меньше второй «str1 < str2»: «TRUE», когда str1 меньше str2 по алфавитному порядку. Например, « огонь < дерево », поскольку «о» находится дальше к началу алфавитного ряда, чем «д».
- Длина строки равна 0 « -z str2»: при выполнении этого условия возвращается «TRUE».
- Длина строки отлична от нулевого значения « -n str2»: «TRUE», если условие выполняется.
Пример скрипта для сравнения двух строковых переменных
Создание тестового файла
Обработка строк не является единственной особенностью консольных окружений Ubuntu. В них можно обрабатывать текстовые массивы данных.
- Для практического изучения команд, с помощью которых выполняется работа с текстом в интерпретаторе bash, необходимо создать текстовый файл txt .
- После этого нужно наполнить его произвольным текстом, разделив его на строки. Новая строка не должна сливаться с другими элементами.
- Далее нужно перейти в директорию, в которой находится файл, и запустить терминал с помощью сочетания клавиш — Ctrl+Alt+T.
Основы работы с grep
Поиск строки в файле операционной системы Linux Ubuntu осуществляется посредством специальной утилиты — grep . Она позволяет также отфильтровать вывод информации в консоли. Например, вывести все ошибки из log-файла утилиты ps или найти PID определенного процесса в ее отчете.
Команда grep работает с шаблонами и регулярными выражениями. Кроме того, она применяется с другими командами интерпретатора bash.
Синтаксис команды
Для работы с утилитой grep необходимо придерживаться определенного синтаксиса
- grep [options] pattern [file_name1 file_name2 file_nameN] (где «options» — дополнительные параметры для указания настроек поиска и вывода результата; «pattern» — шаблон, представляющий строку поиска или регулярное выражение, по которым будет осуществляться поиск; «file_name1 file_name2 file_nameN» — имя одного или нескольких файлов, в которых производится поиск).
- instruction | grep [options] pattern (где «instruction» — команда интерпретатора bash, «options» — дополнительные параметры для указания настроек поиска и вывода результата, «pattern» — шаблон, представляющий строку поиска или регулярное выражение, по которым будет производиться поиск).
Основные опции
Практическое применение grep
Поиск подстроки в строке
В окне терминала выводятся все строки, содержащие подстроку. Найденные совпадения подсвечиваются другим цветом.
- С учетом регистра:
- Без учета регистра:
Вывод нескольких строк
- Строка с вхождением и две после нее:
- Строка с вхождением и три до нее:
- Строка, содержащая вхождение, и одну до и после нее:
Чтение строки из файла с использованием регулярных выражений
Регулярные выражения расширяют возможности поиска и позволяют выполнить разбор строки на отдельные элементы. Они активируются при помощи ключа -e.
Чтобы вывести первый символ строки, нужно воспользоваться конструкцией
Если воспользоваться числовыми интервалами, то можно вывести все строки, в которых встречаются числа:
Рекурсивный режим поиска
- Чтобы найти строку или слово в нескольких файлах, расположенных в одной папке, нужно использовать рекурсивный режим поиска:
- Если нет необходимости выводить имена файлов, содержащих искомую строку, то можно воспользоваться ключом-параметром деактивации отображения имен:
Точное вхождение
При поиске союза «и» grep будет выводить все строки, в которых он содержится. Чтобы этого избежать, требуется использовать специальный ключ « w »:
Поиск нескольких слов
Утилита «w» позволяет искать не только одно слово, но и несколько одновременно
Количество строк в файле
При помощи grep можно определить число вхождений строки или подстроки в текстовом файле и вывести ее номер.
- Число вхождений:
- Номера строк с совпадениями:
Инверсия
Если в тексте требуется найти определенные строки, которые не содержат какого-либо слова или подстроки, то рекомендуется использовать инверсионный режим поиска.
Вывод только имени файла
Чтобы не выводить все строки с совпадением, а вывести только имя файла, нужно воспользоваться конструкцией:
Использование sed
Потоковый текстовый редактор « sed » встроен в bash Linux Ubuntu. Он использует построчное чтение, а также позволяет выполнить фильтрацию и преобразование текста.
Синтаксис
Для работы с потоковым текстовым редактором sed используется следующий синтаксис:
sed [options] instructions [file_name] (где «options» — ключи-опции для указания метода обработки текста, «instructions» — команда, совершаемая над найденным фрагментом текста, «file_name» — имя файла, над которым совершаются действия).
Для вывода всех опций потокового текстового редактора нужно воспользоваться командой:
Распространенные конструкции с sed
Замена слова
Например, если требуется заменить строку в файле или слово с «команды» на «инструкции». Для этого нужно воспользоваться следующими конструкциями:
Редактирование файла
Чтобы записать строку в файл, нужно указать параметр замены одной строки на другую, воспользовавшись ключом — -i :
После выполнения команды произойдет замена слова «команды» на «инструкции» с последующим сохранением файла.
Удаление строк из файла
- Удалить первую строку из файла:
- Удалить строку из файла, содержащую слово«окне»:
Нумерация строк
Строки в файле будут пронумерованы следующим образом: первая строка — 1, вторая — 2 и т. д.
Следует обратить внимание, что нумерация начинается не с «0», как в языках программирования.
Удаление всех чисел из текста
Замена символов
Чтобы заменить набор символов, нужно воспользоваться инструкцией, содержащей команду « y »:
Обработка указанной строки
Утилита производит манипуляции не только с текстом, но и со строкой, указанной в правиле шаблона (3 строка):
Работа с диапазоном строк
Для выполнения замены только в 3 и 4 строках нужно использовать конструкцию:
Пробую написать небольшой скрипт на bash и уже в самом начале проблема. Создаю две переменные и пытаюсь их соединить, но вместо этого происходит какая-то ересь, прошу помощи. Гугл ответа пока не дал.
В результате получаю ответ вида:
Как я понял символы второй строки просто перезаписывает символы первой, до тех пор, пока символы второй строки не закончатся. Но как заставить это работать как надо понять не смог.
Пробовал без скобок, с использованием плюса, соединять в двойных кавычках, и подобные способы.
P.S. Строки переписал под тестовые, на деле использую нормальный адрес, но проблема даже с этими строками сохраняется.
Попробуйте сделать так
UPD
Воссоздал ситуацию. Такое поведение возникает если скрипт записан следующим образом:
Но для того, чтобы его так записать, надо еще постараться.
Для решения проблемы нужно каждую логическую строку закончить символом точки с запятой ';'.
Прочитав комментарии понял что проблема кроется в одном или сразу всех далее следующих факторах.
Баг появляется если работать в windows, писать скрипт в файле, через ide, в данном случае netbeans, но возможно и фв других ide повторится, и запускать его через cygwin консоль, возможно так же повторится и в других подобных терминалах.
Пример рабочего скрипта.
В общем, для объединения двух переменных вы можете просто записать их одну за другой:
Ответ 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:
с обратными чертами вы должны выходить из внутренних вилок с помощью обратной косой черты:
Читайте также: