Bash строки: Работа со строками в командном интерпретаторе bash 📝

Содержание

Работа со строками в командном интерпретаторе bash 📝

Работа со строками в 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», если условие выполняется.

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

  1. Чтобы сравнить две строки, нужно написать bash-скрипт с именем test.
  2. Далее необходимо открыть терминал и запустить test на выполнение командой:
    ./test
  3. Предварительно необходимо дать файлу право на исполнение командой:
    chmod +x test
  4. После указания пароля скрипт выдаст сообщение на введение первого и второго слова. Затем требуется нажать клавишу «Enter» для получения результата сравнения.

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

Обработка строк не является единственной особенностью консольных окружений 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» — шаблон, представляющий строку поиска или регулярное выражение, по которым будет производиться поиск).

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

  • Отобразить в консоли номер блока перед строкой — -b.
  • Число вхождений шаблона строки —
    .
  • Не выводить имя файла в результатах поиска — -h.
  • Без учета регистра — -i.
  • Отобразить только имена файлов с совпадением строки — -l.
  • Показать номер строки — -n.
  • Игнорировать сообщения об ошибках — -s.
  • Инверсия поиска (отображение всех строк, в которых не найден шаблон) — -v.
  • Слово, окруженное пробелами, — -w.
  • Включить регулярные выражения при поиске — -e.
  • Отобразить вхождение и N строк до и после него — -An и -Bn соответственно.
  • Показать строки до и после вхождения — -Cn.

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

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

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

Вывод нескольких строк
  • Строка с вхождением и две после нее:
    grep -A2 "Bourne"txt
  • Строка с вхождением и три до нее:
    grep -B3 "Bourne"txt
  • Строка, содержащая вхождение, и одну до и после нее:
    grep -C1 "Bourne"txt
Чтение строки из файла с использованием регулярных выражений

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

  • Вывод строки, в начале которой встречается слово «Фамилия».
    В регулярных выражения для обозначения начала строки используется специальный символ
    «^»
    .
    grep "^Фамилия" firstfile.txt

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

    grep "^Ф" firstfile.txt
  • Конец строки, заканчивающийся словом «оболочка»Для обозначения конца строки используется мета-символ «$».
    grep “оболочка$” firstfile.txt Если требуется вывести символ конца строки, то следует применять конструкцию
    grep “а.$” firstfile.txt. В этом случае будут выведены все строки, заканчивающиеся на литеру «а».
  • Строки, содержащие числа.
    grep -C1 "Bourne"txt

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

    grep "[0-9]"txt
Рекурсивный режим поиска
Точное вхождение

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

grep -w "и" firstfile.txt
Поиск нескольких слов

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

grep -w "и | но" firstfile.txt
Количество строк в файле

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

  • Число вхождений:
    grep -с "Bourne"txt
  • Номера строк с совпадениями:
    grep -n "Bourne"txt

Инверсия

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

grep -v "Unix" firstfile.txt
Вывод только имени файла

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

grep -I "Unix" *.txt

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

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

Синтаксис

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

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

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

sed --help

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

Замена слова

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

  • Для первого вхождения:
    sed 's/команды/инструкции/' firstfile.txt

  • Для всех вхождений (используется параметр инструкции — g):
    sed 's/команды/инструкции/g' firstfile.txt
  • Замена подстроки с несколькими условиями (используется ключ — -e):
    sed -e 's/команды/инструкции/g' -e 's/команд/инструкций/g' firstfile.txt
  • Заменить часть строки, если она содержит определенный набор символов (например, POSIX):
    sed '/POSIX/s/Bash/оболочка/g' firstfile.txt
  • Выполнить замену во всех строках, начинающихся на «Bash»
    sed '/^Bash/s/Bash/оболочка/g' firstfile.txt
  • Произвести замену только в строках, которые заканчиваются на «Bash»:
    sed '/команды/s/Bash/оболочка/g' firstfile.txt
  • Заменить слово с пробелом на слово с тире:
    sed 's/Bash\ /оболочка-/g' firstfile.txt
  • Заменить символ переноса строки на пробел
    sed 's/\n/ /g' firstfile.txt
  • Перенос строки обозначается символом — \n.
Редактирование файла

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

sed -i 's/команды/инструкции/' firstfile.txt

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

Удаление строк из файла
  • Удалить первую строку из файла:
    sed -i '1d' firstfile.txt
  • Удалить строку из файла, содержащую слово «окне»:
    sed '/окне/d' firstfile.txt

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

  • Удалить пустые строки:
    sed '/^$/d' firstfile.txt
  • Убрать пробелы в конце строки:
    sed 's/ *$//' firstfile.txt
  • Табуляция удаляется при помощи конструкции:
    sed 's/\t*$//' firstfile.txt
  • Удалить последний символ в строке:
    sed 's/ ;$//' firstfile.txt
Нумерация строк

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

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

sed = firstfile.txt | sed 'N;s/\n/\t/'
Удаление всех чисел из текста
sed -i 's/\[0-9\] \ [0-9\]//g' firstfile.txt
Замена символов

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

sed 'y/1978/1977/g' firstfile.txt
Обработка указанной строки

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

sed '3s/директорий/папок' firstfile.txt
Работа с диапазоном строк

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

sed '3,4s/директорий/папок' firstfile.txt

Вставка содержимого файла после строки

Иногда требуется вставить содержимое одного файла (input_file.txt) после определенной строки другого (firstfile.txt). Для этой цели используется команда:
sed ‘5r input_file.txt’ firstfile.txt (где «5r» — 5 строка, «input_file.txt» — исходный файл и «firstfile.txt» — файл, в который требуется вставить массив текста).

Работа со строками string bash

Допустим у вас есть переменная str. В этой переменной некий текст в виде строки. Как вывести несколько символов из строки? Выводить текст при помощи цикла — это довольно долгое занятие. Поможет простая конструкция {?}. Вы можете вывести часть строки, передав параметр ${str:?}. Вместо ? поставьте индекс позиции символа. ${str:начало:конец} тут вы можете вывести значения согласно выбранному интервалу. Посмотрите на пример.


#!/bin/bash
str=abcABC123ABCabc
# 0123456789.....# Индексация начинается с 0.
echo ${str:0} # abcABC123ABCabc
echo ${str:1} # bcABC123ABCabc
echo ${str:7} # 23ABCabc
echo ${str:7:3} # 23A # Извлекает 3 символа.
# Возможна ли индексация с "правой" стороны строки?

echo ${str:-4} # abcABC123ABCabc
# По-умолчанию выводится полная строка.
# Однако . . .echo ${str:(-4)} # Cabc

echo ${str: -4} # Cabc
# Теперь выводится правильно.
# Круглые скобки или дополнительный пробел "экранируют" параметр позиции.

Как определить позицию индекс строки? Посмотрите на пример. expr — универсальный обработчик выражений: вычисляет заданное выражение (аргументы должны отделяться пробелами). Выражения могут быть логическими, арифметическими или строковыми.


#!/bin/bash
str=abcABC123ABCabc

echo `expr index "$str" C12` 
#вывод: 6 
# позиция символа C.

echo `expr index "$str" 1c` 
#вывод: 3
# символ 'c' (в #3 позиции) совпал раньше, чем '1'.

#количество символов в строке
echo ${#str} # 15
echo `expr length $str` # 15
echo `expr "$str" : '.*'` # 15

Покажу поиск строк при помощи регулярных выражений. В примере все вышеприведенные операции дают один и тот же результат.


#!/bin/bash
str=abcABC123ABCabc

echo `expr match "$str" '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1
echo `expr "$str" : '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1
echo `expr "$str" : '\(.......\)'` # abcABC1

просмотры: 6173, уровень: лёгкий уровень, рейтинг: 5, дата: 2017-05-29 13:45:09

Комментарии:

Лекция №24 — bash работа со строками « Информационный конспект

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

Во многих скриптах системы вы можете увидеть запись наподобие этой:

1

. /lib/lsb/init-functions

Это точка, после которой обязательно следует пробел и далее путь к файлу. Не путайте это с вариантом без пробела — ./lib/lsb/init-functionsТочка с пробелом после которой следует путь к текстовому файлу позволяет загрузить текст этого файла в текущий скрипт. Данный механизм можно сравнить с командой include в языке С. Этот механизм имеет большое практическое применение. Например, можно описать часто употребляемые функции в отдельном файле, а далее пользоваться функциями в других скриптах. Этот же механизм используется и для создания конфигурационных файлов. Рассмотрим практический пример. Создадим файл с именем testopt и со следующим содержанием:

1
2
3
4

#Конфигурационный файл
#Задаем опцию вывода на экран:
PRINT=YES
PRINT2=NO

Затем создадим еще один файл-скрипт с именем printopt.sh в том же каталоге, что и файл testopt:

1
2
3
4

#!/bin/bash
. testopt
if [ $PRINT = «YES» ]; then echo «PRINT»; fi
if [ $PRINT2 = «YES» ]; then echo «PRINT2»; fi

Когда интерпретатор bash начнет разбирать при запуске скрипт printopt.sh, то благодаря конструкции . testoptисполняемый файл будет для интерпретатора иметь следующий вид:

1
2
3
4
5
6
7

#!/bin/bash
#Конфигурационный файл
#Задаем опцию вывода на экран:
PRINT=YES
PRINT2=NO
if [ $PRINT = «YES» ]; then echo «PRINT»; fi
if [ $PRINT2 = «YES» ]; then echo «PRINT2»; fi

То есть на место . testopt подставляется содержимое (текст) файла testopt. Результат работы скрипта:

1
2

[email protected]:~/linux$ ./printopt.sh
PRINT

Работа со строками

Рассмотрим несколько приемов обработки строк в bash. Допустим есть переменная А, которой присвоена строка “QWERTY“. Чтобы вывести содержимое переменной на экран достаточно написать echo $A:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo $A
QWERTY

Допустим хотим вывести такую строку — QWERTASD. Вариант $AASD не сработает, так как для bash — AASDбудет несуществующей переменной:

1

[email protected]:~/linux$ A=»QWERTY»; echo $AASD

Поэтому записать следует так: ${A}ASD:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo ${A}ASD
QWERTYASD

Если необходимо отобразить строку с N-го символа, тогда используем конструкцию ${A:N}, где N — номер символа с которого будет отображена строка. Символы в строке ведут нумерацию с нуля. Чтобы отобразить ERTYпишем:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo ${A:2}
ERTY

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

Можно отобразить определенное количество символов начинаю с определенной позиции. Тогда записать нужно так ${A:N:M}, где N — номер символа с которого будет отображена строка, а M — количество отображаемых символов. Чтобы вывести из нашей строки QWERTY символы ER пишем:

1
2

[email protected]:~$ A=»QWERTY»; echo ${A:2:2}
ER

Чтобы вывести QWE пишем так:

1
2

[email protected]:~$ A=»QWERTY»; echo ${A::3}
QWE

Рассмотрим вот такую конструкцию:

1
2
3
4

[email protected]:~$ A=»ABABABCDCD»; echo ${A#AB}
ABABCDCD
[email protected]:~$ A=»123ABABABCDCD»; echo ${A#AB}
123ABABABCDCD

После символа # указываем шаблон, и если начало строки совпадает с этим шаблоном, то строка будет выведена без символов удовлетворяющих шаблону. Строка “123ABABABCDCD” начинается с 12 и шаблон AB не сработал, а вот если написать #*AB (или #???AB), то получим следующий результат:

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A#*AB}

ABABCDCD
[email protected]:~$ A=»123ABABABCDCD»; echo ${A#???AB}
ABABCDCD

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

1
2

[email protected]:~$ A=»123ABABABCDCD»; echo ${A##*AB}
CDCD

Если у нас стоит один знак # то от строки отделяется минимум удовлетворяющий шаблону. То есть для“123ABABABCDCD” — это “123AB”. А если у нас два знака ##, то отделяется максимально возможная часть удовлетворяющая шаблону. То есть То есть для “123ABABABCDCD” — это “123ABABAB”, так как 123ABABподходит под *.

Если необходимо таким же образом убрать символы начиная с конца строки, то вместо 

# используем %. Правила те же, что и для #.

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A%AB*}
123ABAB
[email protected]:~$ A=»123ABABABCDCD»; echo ${A%%AB*}
123

Теперь посмотрим как в bash можно выполнять замену символов в строке. Допустим нужно в нашей строке“123ABABABCDCD” заменить символы AB на ZX, чтобы получилась строка “123ZXZXZXCDCD”. Для этого используем / или // и пишем так::

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A/AB/ZX}
123ZXABABCDCD

[email protected]:~$ A=»123ABABABCDCD»; echo ${A//AB/ZX}
123ZXZXZXCDCD

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

1
2
3
4
5
6

[email protected]:~$ echo ${options:=»YES»}
YES
[email protected]:~$ echo $options
YES
[email protected]:~$ options=»NO»; echo ${options:=»YES»}
NO

Команду ${options:=”YES”} следует понимать так: если переменная options не существует, значит необходимосоздать ее и присвоить значение “YES”, а если переменная options существует, то используем ее истинное значение. В команде из последнего примера (строка 1), переменная 

options не существовала, поэтому она была создана и ей было присвоено значение YES, в следующей команде (строка 3), мы видим, что действительно переменная options была создана и ей было присвоено значение.
В следующей команде (строка 5) переменная options была создана со значением NO (то есть она существовала до команды echo ${options:=”YES”}) и поэтому было выведено именно это значение (NO).

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

1
2
3
4

[email protected]:~$ echo ${options1:-«YES»}
YES
[email protected]:~$ echo $options1

.

То есть, если переменная не существует, то она не создается, а вместо ее несуществующего значения используется указанное (в примере это “YES”). Данная конструкция работает если переменной не существует или она существует, но со значением нулевой длины.

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

1
2
3
4

[email protected]:~$ options=»NO»; echo ${options:+»YES»}
YES
[email protected]:~$ echo $options
NO

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

Команда read

Для некоторых видов скриптов (например инсталляционных), необходимо, чтобы пользователь вводил какие либо значения, и они могли быть использованы далее в скрипте. Для решения этой задачи в bash существует команда read. В простейшем случае команда записывается так: read P1 P2 …. PN, где P1 … PN — это имена параметров через пробел. Команда read считывает данные из потока ввода и записывает их в указанные переменные. В качестве разделителя для вводимых данных команда read использует значение которое хранится в системной переменой bash — IFS. Как правило — это пробел или табуляция. Рассмотрим пример скрипта:

1
2
3
4
5

#!/bin/bash
echo «Наберите ваши имя и фамилию через пробел и нажмите Enter:»
read P1 P2
echo «Ваше имя:$P1»
echo «Ваша фамилия:$P2»

И результат выполнения:

1
2
3
4
5

[email protected]:~/linux$ ./hello.sh
Наберите ваши имя и фамилию через пробел и нажмите Enter:
Igor Kuzmenko
Ваше имя:Igor
Ваша фамилия:Kuzmenko

Если изменить 5-ю строку скрипта на echo “Ваша фамилия:${P2:-”Фамилия отсутствовала”}”, то тогда, если не ввести фамилию будет выполнена подстановка указанного значения:

1
2
3
4
5

[email protected]:~/linux$ ./hello.sh
Наберите ваши имя и фамилию через пробел и нажмите Enter:
Игорь
Ваше имя:Игорь
Ваша фамилия:Фамилия отсутствовала

Команда read может выполняться с ключами. Наиболее значимые это:

-n — позволяет задать количество символов которое необходимо считать из потока ввода;
-t — позволяет задать количество секунд ожидания данных. Если пользователь ничего не ввел, то по истечении этого времени команда завершиться с ошибкой и скрипт будет выполнятся дальше.
-s — запрещает отображение вводимой информации на консоли. Используется для ввода конфиденциальной информации.

Справку о команде read можно получить из консоли по команде help read.

На этом наше знакомство с bash завершается. Рекомендую просмотреть скрипты из каталога /etc/init.d/, и попробовать понять теперь, что каждый из них выполняет. Так вы лучше поймете, что происходит при запуске той или иной службы или ее завершении, а соответственно и при запуске и завершении самой системы Linux. Мы конечно же рассмотрели не все команды. Хочу еще раз напомнить, что в bash могут использоваться как встроенные команды так и внешние. Если вы видите в скриптах незнакомую команду (возьмем к примеру ту жеread) и нет справки о ней по команде man read, вероятно это встроенная в bash команда нужно смотреть либо вman bash либо использовать help read.

Взято с http://igorka.com.ua/2009-12-29/lekciya-24-bash-rabota-so-strokami/

Понравилось это:

Нравится Загрузка…

Похожее

Igorka: Лекция №24 — bash работа со строками

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

Во многих скриптах системы вы можете увидеть запись наподобие этой:

1

. /lib/lsb/init-functions

Это точка, после которой обязательно следует пробел и далее путь к файлу. Не путайте это с вариантом без пробела — ./lib/lsb/init-functions. Точка с пробелом после которой следует путь к текстовому файлу позволяет загрузить текст этого файла в текущий скрипт. Данный механизм можно сравнить с командой include в языке С. Этот механизм имеет большое практическое применение. Например, можно описать часто употребляемые функции в отдельном файле, а далее пользоваться функциями в других скриптах. Этот же механизм используется и для создания конфигурационных файлов. Рассмотрим практический пример. Создадим файл с именем testopt и со следующим содержанием:

1
2
3
4

#Конфигурационный файл
#Задаем опцию вывода на экран:
PRINT=YES
PRINT2=NO

Затем создадим еще один файл-скрипт с именем printopt.sh в том же каталоге, что и файл testopt:

1
2
3
4

#!/bin/bash
. testopt
if [ $PRINT = «YES» ]; then echo «PRINT»; fi
if [ $PRINT2 = «YES» ]; then echo «PRINT2»; fi

Когда интерпретатор bash начнет разбирать при запуске скрипт printopt.sh, то благодаря конструкции . testopt исполняемый файл будет для интерпретатора иметь следующий вид:

1
2
3
4
5
6
7

#!/bin/bash
#Конфигурационный файл
#Задаем опцию вывода на экран:
PRINT=YES
PRINT2=NO
if [ $PRINT = «YES» ]; then echo «PRINT»; fi
if [ $PRINT2 = «YES» ]; then echo «PRINT2»; fi

То есть на место . testopt подставляется содержимое (текст) файла testopt. Результат работы скрипта:

1
2

[email protected]:~/linux$ ./printopt.sh
PRINT

Работа со строками

Рассмотрим несколько приемов обработки строк в bash. Допустим есть переменная А, которой присвоена строка “QWERTY“. Чтобы вывести содержимое переменной на экран достаточно написать echo $A:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo $A
QWERTY

Допустим хотим вывести такую строку — QWERTASD. Вариант $AASD не сработает, так как для bashAASD будет несуществующей переменной:

1

[email protected]:~/linux$ A=»QWERTY»; echo $AASD

Поэтому записать следует так: ${A}ASD:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo ${A}ASD
QWERTYASD

Если необходимо отобразить строку с N-го символа, тогда используем конструкцию ${A:N}, где N — номер символа с которого будет отображена строка. Символы в строке ведут нумерацию с нуля. Чтобы отобразить ERTY пишем:

1
2

[email protected]:~/linux$ A=»QWERTY»; echo ${A:2}
ERTY

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

Можно отобразить определенное количество символов начинаю с определенной позиции. Тогда записать нужно так ${A:N:M}, где N — номер символа с которого будет отображена строка, а M — количество отображаемых символов. Чтобы вывести из нашей строки QWERTY символы ER пишем:

1
2

[email protected]:~$ A=»QWERTY»; echo ${A:2:2}
ER

Чтобы вывести QWE пишем так:

1
2

[email protected]:~$ A=»QWERTY»; echo ${A::3}
QWE

Рассмотрим вот такую конструкцию:

1
2
3
4

[email protected]:~$ A=»ABABABCDCD»; echo ${A#AB}
ABABCDCD
[email protected]:~$ A=»123ABABABCDCD»; echo ${A#AB}
123ABABABCDCD

После символа # указываем шаблон, и если начало строки совпадает с этим шаблоном, то строка будет выведена без символов удовлетворяющих шаблону. Строка “123ABABABCDCD” начинается с 12 и шаблон AB не сработал, а вот если написать #*AB (или #???AB), то получим следующий результат:

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A#*AB}
ABABCDCD
[email protected]:~$ A=»123ABABABCDCD»; echo ${A#???AB}
ABABCDCD

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

1
2

[email protected]:~$ A=»123ABABABCDCD»; echo ${A##*AB}
CDCD

Если у нас стоит один знак # то от строки отделяется минимум удовлетворяющий шаблону. То есть для “123ABABABCDCD” — это “123AB”. А если у нас два знака ##, то отделяется максимально возможная часть удовлетворяющая шаблону. То есть То есть для “123ABABABCDCD” — это “123ABABAB”, так как 123ABAB подходит под *.

Если необходимо таким же образом убрать символы начиная с конца строки, то вместо # используем %. Правила те же, что и для #.

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A%AB*}
123ABAB
[email protected]:~$ A=»123ABABABCDCD»; echo ${A%%AB*}
123

Теперь посмотрим как в bash можно выполнять замену символов в строке. Допустим нужно в нашей строке “123ABABABCDCD” заменить символы AB на ZX, чтобы получилась строка “123ZXZXZXCDCD”. Для этого используем / или // и пишем так::

1
2
3
4

[email protected]:~$ A=»123ABABABCDCD»; echo ${A/AB/ZX}
123ZXABABCDCD
[email protected]:~$ A=»123ABABABCDCD»; echo ${A//AB/ZX}
123ZXZXZXCDCD

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

1
2
3
4
5
6

[email protected]:~$ echo ${options:=»YES»}
YES
[email protected]:~$ echo $options
YES
[email protected]:~$ options=»NO»; echo ${options:=»YES»}
NO

Команду ${options:=”YES”} следует понимать так: если переменная options не существует, значит необходимо создать ее и присвоить значение “YES”, а если переменная options существует, то используем ее истинное значение. В команде из последнего примера (строка 1), переменная options не существовала, поэтому она была создана и ей было присвоено значение YES, в следующей команде (строка 3), мы видим, что действительно переменная options была создана и ей было присвоено значение.
В следующей команде (строка 5) переменная options была создана со значением NO (то есть она существовала до команды echo ${options:=”YES”}) и поэтому было выведено именно это значение (NO).

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

1
2
3
4

[email protected]:~$ echo ${options1:-«YES»}
YES
[email protected]:~$ echo $options1
                                                                          .

То есть, если переменная не существует, то она не создается, а вместо ее несуществующего значения используется указанное (в примере это “YES”). Данная конструкция работает если переменной не существует или она существует, но со значением нулевой длины.

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

1
2
3
4

[email protected]:~$ options=»NO»; echo ${options:+»YES»}
YES
[email protected]:~$ echo $options
NO

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

Команда read

Для некоторых видов скриптов (например инсталляционных), необходимо, чтобы пользователь вводил какие либо значения, и они могли быть использованы далее в скрипте. Для решения этой задачи в bash существует команда read. В простейшем случае команда записывается так: read P1 P2 …. PN, где P1 … PN — это имена параметров через пробел. Команда read считывает данные из потока ввода и записывает их в указанные переменные. В качестве разделителя для вводимых данных команда read использует значение которое хранится в системной переменой bashIFS. Как правило — это пробел или табуляция. Рассмотрим пример скрипта:

1
2
3
4
5

#!/bin/bash
echo «Наберите ваши имя и фамилию через пробел и нажмите Enter:»
read P1 P2
echo «Ваше имя:$P1»
echo «Ваша фамилия:$P2»

И результат выполнения:

1
2
3
4
5

[email protected]:~/linux$ ./hello.sh
Наберите ваши имя и фамилию через пробел и нажмите Enter:
Igor Kuzmenko
Ваше имя:Igor
Ваша фамилия:Kuzmenko

Если изменить 5-ю строку скрипта на echo “Ваша фамилия:${P2:-”Фамилия отсутствовала”}”, то тогда, если не ввести фамилию будет выполнена подстановка указанного значения:

1
2
3
4
5

[email protected]:~/linux$ ./hello.sh
Наберите ваши имя и фамилию через пробел и нажмите Enter:
Игорь
Ваше имя:Игорь
Ваша фамилия:Фамилия отсутствовала

Команда read может выполняться с ключами. Наиболее значимые это:

-n — позволяет задать количество символов которое необходимо считать из потока ввода;
-t — позволяет задать количество секунд ожидания данных. Если пользователь ничего не ввел, то по истечении этого времени команда завершиться с ошибкой и скрипт будет выполнятся дальше.
-s — запрещает отображение вводимой информации на консоли. Используется для ввода конфиденциальной информации.

Справку о команде read можно получить из консоли по команде help read.

На этом наше знакомство с bash завершается. Рекомендую просмотреть скрипты из каталога /etc/init.d/, и попробовать понять теперь, что каждый из них выполняет. Так вы лучше поймете, что происходит при запуске той или иной службы или ее завершении, а соответственно и при запуске и завершении самой системы Linux. Мы конечно же рассмотрели не все команды. Хочу еще раз напомнить, что в bash могут использоваться как встроенные команды так и внешние. Если вы видите в скриптах незнакомую команду (возьмем к примеру ту же read) и нет справки о ней по команде man read, вероятно это встроенная в bash команда нужно смотреть либо в man bash либо использовать help read.

Читать другие лекции по курсу Администратор ПК с Linux

Строковые операции в Bash | ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)

Давайте поработаем со строками!

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

Но это не значит, что у вас нет функций манипулирования строками.

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

 

Получить длину строки

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

Строка – это не что иное, как последовательность (массив) символов. Создадим строку с именем distro и инициализируем ее значением «Ubuntu».

distro="Ubuntu"

 

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

[email protected]:~/scripts$ echo ${#distro}
6

 

Обратите внимание, что команда echo предназначена для печати значения {#string} это то, что дает длину строки.

 

Соединение двух строк

Вы можете добавить строку в конец другой строки; этот процесс называется конкатенацией строк.

Для демонстрации давайте сначала создадим две строки str1 и str2 следующим образом:

str1="And"
str2="reyEx"

 

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

str3=$str1$str2

 

Не может быть проще, не так ли?

 

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

Вы можете найти позицию (индекс) конкретной буквы или слова в строке. Для демонстрации давайте сначала создадим строку с именем str следующим образом:

str="Bash is Cool"

 

Теперь вы можете получить конкретную позицию (индекс) подстроки cool. Для этого используйте команду expr:

[email protected]:~/scripts$ word="Cool"
[email protected]:~/scripts$ expr index "$str" "$word"
9

Результат 9 – это индекс, с которого начинается слово «Cool» в строке str.

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

 

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

Для демонстрации давайте сначала создадим строку с именем foss следующим образом:

foss="Fedora is a free operating system"

 

Теперь предположим, что вы хотите извлечь первое слово «Fedora» в строке foss. Вам необходимо указать начальную позицию (индекс) желаемой подстроки и количество символов, которые вам нужно извлечь.

Следовательно, чтобы извлечь подстроку «Fedora», вы будете использовать 0 в качестве начальной позиции, и вы извлечете 6 символов из начальной позиции:

[email protected]:~/scripts$ echo ${foss:0:6}
Fedora

 

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

Например, чтобы извлечь подстроку «свободная операционная система» из строки foss ; нам нужно только указать начальную позицию 12:

[email protected]:~/scripts$ echo ${foss:12}
free operating system

 

Замена подстрок

Вы также можете заменить подстроку другой подстрокой; например, вы можете заменить «Fedora» на «Ubuntu» в строке foss следующим образом:

[email protected]:~/scripts$ echo ${foss/Fedora/Ubuntu}
Ubuntu is a free operating system

 

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

[email protected]:~/scripts$ echo ${foss/free/popular}
Fedora is a popular operating system

 

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

 

Удаление подстрок

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

fact="Sun is a big star"

 

Теперь вы можете удалить подстроку big из строки fact:

[email protected]:~/scripts$ echo ${fact/big}
Sun is a star

 

Создадим еще одну строку с именем cell:

cell="112-358-1321"

 

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

[email protected]:~/scripts$ echo ${cell/-}
112358-1321

 

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

[email protected]:~/scripts$ echo ${cell//-}
1123581321

 

Обратите внимание, что вы используете эхо-операторы, поэтому строка ячейки не повреждена и не изменена; вы просто демонстрируете желаемый результат!

Чтобы изменить строку, вам нужно вернуть результат в строку следующим образом:

[email protected]:~/scripts$ echo $cell
112-358-1321
[email protected]:~/scripts$ cell=${cell//-}
[email protected]:~/scripts$ echo $cell
1123581321

 

Преобразование прописных и строчных букв в строку

Вы также можете преобразовать строку в строчные или прописные буквы. Сначала создадим две строки с именами легенда и актер:

legend="john nash"
actor="JULIA ROBERTS"

 

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

[email protected]:~/scripts$ echo ${legend^^}
JOHN NASH

 

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

[email protected]:~/scripts$ echo ${actor,,}
julia roberts

 

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

[email protected]:~/scripts$ echo ${legend^}
John nash

 

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

[email protected]:~/scripts$ echo ${actor,}
jULIA ROBERTS

 

Вы также можете изменить некоторые символы в строке на верхний или нижний регистр; например, вы можете изменить буквы jи nна верхний регистр в строке легенды следующим образом:

[email protected]:~/scripts$ echo ${legend^^[jn]}
JohN Nash

 

На этом мы подошли к концу этой статьи из серии bash для начинающих. Надеюсь, вам понравилось манипулировать строками в bash.

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

Как проверить, содержит ли строка подстроку в Bash

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

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

 

Самый простой подход заключается в том, чтобы окружить подстроку подстановочными символами звездочки (звездочкой) * и сравнить ее со строкой. Подстановочный знак – это символ, используемый для обозначения нуля, одного или нескольких символов.

Если тест возвращается true, подстрока содержится в строке.

В приведенном ниже примере мы используем оператор if и оператор равенства ( =

, чтобы проверить SUB, найдена ли подстрока в строке STR:
#!/bin/bash

STR='GNU/Linux это операционная система'
SUB='Linux'
if [[ "$STR" == *"$SUB"* ]]; then
  echo "Присутствует."
fi

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

Присутствует.

Вместо использования оператора if вы также можете использовать оператор case, чтобы проверить, содержит ли строка другую строку.

#!/bin/bash

STR='GNU/Linux это операционная система'
SUB='Linux'

case $STR in

  *"$SUB"*)
    echo -n "Присутствует."
    ;;
esac

Другим вариантом определения того, встречается ли указанная подстрока в строке, является использование оператора регулярного выражения =~. Когда используется этот оператор, правильная строка рассматривается как регулярное выражение.

Точка, за которой следует звездочка .* соответствует нулю или большему количеству вхождений любого символа, кроме символа новой строки.

#!/bin/bash

STR='GNU/Linux это операционная система'
SUB='Linux'

if [[ "$STR" =~ .*"$SUB".* ]]; then
  echo "Присутствует."
fi

Скрипт отобразит следующее:

Присутствует.

Команда grep также может использоваться для поиска строк в другой строке.

В следующем примере мы передаем строку $STR в качестве входных данных для grep и проверяем $SUB, найдена ли строка во входной строке. Команда вернет true или false при необходимости.

#!/bin/bash

STR='GNU/Linux это операционная система'
SUB='Linux'

if grep -q "$SUB" <<< "$STR"; then
  echo "Присутствует"
fi

Опция -q говорит Grep, чтобы быть спокойным и пропустить выход.

 

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

Прочитав эту статью, вы должны хорошо понимать, как проверить, содержит ли строка другую строку. Вы также можете использовать другие команды, такие как команда awk или sed для тестирования.

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

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

sed и обработка текстов / Блог компании RUVDS.com / Хабр

Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит

В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.



Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.

Сейчас мы разберём основы работы с sed, а так же рассмотрим более трёх десятков примеров использования этого инструмента.

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


Утилиту sed называют потоковым текстовым редактором. В интерактивных текстовых редакторах, наподобие nano, с текстами работают, используя клавиатуру, редактируя файлы, добавляя, удаляя или изменяя тексты. Sed позволяет редактировать потоки данных, основываясь на заданных разработчиком наборах правил. Вот как выглядит схема вызова этой команды:
$ sed options file

По умолчанию sed применяет указанные при вызове правила, выраженные в виде набора команд, к STDIN. Это позволяет передавать данные непосредственно sed.

Например, так:

$ echo "This is a test" | sed 's/test/another test/'

Вот что получится при выполнении этой команды.
Простой пример вызова sed

В данном случае sed заменяет слово «test» в строке, переданной для обработки, словами «another test». Для оформления правила обработки текста, заключённого в кавычки, используются прямые слэши. В нашем случае применена команда вида s/pattern1/pattern2/. Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. Sed, выполняя эту команду, просмотрит переданный текст и заменит найденные в нём фрагменты (о том — какие именно, поговорим ниже), соответствующие pattern1, на pattern2.

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

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

$ sed 's/test/another test' ./myfile


Текстовый файл и результаты его обработки

Здесь применён тот же подход, который мы использовали выше, но теперь sed обрабатывает текст, хранящийся в файле. При этом, если файл достаточно велик, можно заметить, что sed обрабатывает данные порциями и выводит то, что обработано, на экран, не дожидаясь обработки всего файла.

Sed не меняет данные в обрабатываемом файле. Редактор читает файл, обрабатывает прочитанное, и отправляет то, что получилось, в STDOUT. Для того, чтобы убедиться в том, что исходный файл не изменился, достаточно, после того, как он был передан sed, открыть его. При необходимости вывод sed можно перенаправить в файл, возможно — перезаписать старый файл. Если вы знакомы с одним из предыдущих материалов этой серии, где речь идёт о перенаправлении потоков ввода и вывода, вы вполне сможете это сделать.

Выполнение наборов команд при вызове sed


Для выполнения нескольких действий с данными, используйте ключ -e при вызове sed. Например, вот как организовать замену двух фрагментов текста:
$ sed -e 's/This/That/; s/test/another test/' ./myfile


Использование ключа -e при вызове sed

К каждой строке текста из файла применяются обе команды. Их нужно разделить точкой с запятой, при этом между окончанием команды и точкой с запятой не должно быть пробела.
Для ввода нескольких шаблонов обработки текста при вызове sed, можно, после ввода первой одиночной кавычки, нажать Enter, после чего вводить каждое правило с новой строки, не забыв о закрывающей кавычке:

$ sed -e '
> s/This/That/
> s/test/another test/' ./myfile

Вот что получится после того, как команда, представленная в таком виде, будет выполнена.
Другой способ работы с sed

Чтение команд из файла


Если имеется множество команд sed, с помощью которых надо обработать текст, обычно удобнее всего предварительно записать их в файл. Для того, чтобы указать sed файл, содержащий команды, используют ключ -f:

Вот содержимое файла mycommands:

s/This/That/
s/test/another test/

Вызовем sed, передав редактору файл с командами и файл для обработки:
$ sed -f mycommands myfile

Результат при вызове такой команды аналогичен тому, который получался в предыдущих примерах.
Использование файла с командами при вызове sed

Флаги команды замены


Внимательно посмотрите на следующий пример.
$ sed 's/test/another test/' myfile

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

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

Схема записи команды замены при использовании флагов выглядит так:

s/pattern/replacement/flags

Выполнение этой команды можно модифицировать несколькими способами.
  • При передаче номера учитывается порядковый номер вхождения шаблона в строку, заменено будет именно это вхождение.
  • Флаг g указывает на то, что нужно обработать все вхождения шаблона, имеющиеся в строке.
  • Флаг p указывает на то, что нужно вывести содержимое исходной строки.
  • Флаг вида w file указывает команде на то, что нужно записать результаты обработки текста в файл.

Рассмотрим использование первого варианта команды замены, с указанием позиции заменяемого вхождения искомого фрагмента:
$ sed 's/test/another test/2' myfile


Вызов команды замены с указанием позиции заменяемого фрагмента

Тут мы указали, в качестве флага замены, число 2. Это привело к тому, что было заменено лишь второе вхождение искомого шаблона в каждой строке. Теперь опробуем флаг глобальной замены — g:

$ sed 's/test/another test/g' myfile

Как видно из результатов вывода, такая команда заменила все вхождения шаблона в тексте.
Глобальная замена

Флаг команды замены p позволяет выводить строки, в которых найдены совпадения, при этом ключ -n, указанный при вызове sed, подавляет обычный вывод:

$ sed -n 's/test/another test/p' myfile

Как результат, при запуске sed в такой конфигурации на экран выводятся лишь строки (в нашем случае — одна строка), в которых найден заданный фрагмент текста.
Использование флага команды замены p

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

$ sed 's/test/another test/w output' myfile


Сохранение результатов обработки текста в файл

Хорошо видно, что в ходе работы команды данные выводятся в STDOUT, при этом обработанные строки записываются в файл, имя которого указано после w.

Символы-разделители


Представьте, что нужно заменить /bin/bash на /bin/csh в файле /etc/passwd. Задача не такая уж и сложная:
$ sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd

Однако, выглядит всё это не очень-то хорошо. Всё дело в том, что так как прямые слэши используются в роли символов-разделителей, такие же символы в передаваемых sed строках приходится экранировать. В результате страдает читаемость команды.

К счастью, sed позволяет нам самостоятельно задавать символы-разделители для использования их в команде замены. Разделителем считается первый символ, который будет встречен после s:

$ sed 's!/bin/bash!/bin/csh!' /etc/passwd

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

Выбор фрагментов текста для обработки


До сих пор мы вызывали sed для обработки всего переданного редактору потока данных. В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:
  • Задать ограничение на номера обрабатываемых строк.
  • Указать фильтр, соответствующие которому строки нужно обработать.

Рассмотрим первый подход. Тут допустимо два варианта. Первый, рассмотренный ниже, предусматривает указание номера одной строки, которую нужно обработать:
$ sed '2s/test/another test/' myfile


Обработка только одной строки, номер который задан при вызове sed

Второй вариант — диапазон строк:

$ sed '2,3s/test/another test/' myfile


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

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

$ sed '2,$s/test/another test/' myfile


Обработка файла начиная со второй строки и до конца

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

$ sed '/likegeeks/s/bash/csh/' /etc/passwd

По аналогии с тем, что было рассмотрено выше, шаблон передаётся перед именем команды s.
Обработка строк, соответствующих фильтру

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

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


Утилита sed годится не только для замены одних последовательностей символов в строках на другие. С её помощью, а именно, используя команду d, можно удалять строки из текстового потока.

Вызов команды выглядит так:

$ sed '3d' myfile

Мы хотим, чтобы из текста была удалена третья строка. Обратите внимание на то, что речь не идёт о файле. Файл останется неизменным, удаление отразится лишь на выводе, который сформирует sed.
Удаление третьей строки

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

Вот как применить команду d к диапазону строк:

$ sed '2,3d' myfile


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

А вот как удалить строки, начиная с заданной — и до конца файла:

$ sed '3,$d' myfile


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

Строки можно удалять и по шаблону:

$ sed '/test/d' myfile


Удаление строк по шаблону

При вызове d можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними:

$ sed '/second/,/fourth/d' myfile


Удаление диапазона строк с использованием шаблонов

Вставка текста в поток


С помощью sed можно вставлять данные в текстовый поток, используя команды i и a:
  • Команда i добавляет новую строку перед заданной.
  • Команда a добавляет новую строку после заданной.

Рассмотрим пример использования команды i:
$ echo "Another test" | sed 'i\First test '


Команда i

Теперь взглянем на команду a:

$ echo "Another test" | sed 'a\First test '


Команда a

Как видно, эти команды добавляют текст до или после данных из потока. Что если надо добавить строку где-нибудь посередине?

Тут нам поможет указание номера опорной строки в потоке, или шаблона. Учтите, что адресация строк в виде диапазона тут не подойдёт. Вызовем команду i, указав номер строки, перед которой надо вставить новую строку:

$ sed '2i\This is the inserted line.' myfile

Команда i с указанием номера опорной строки

Проделаем то же самое с командой a:

$ sed '2a\This is the appended line.' myfile


Команда a с указанием номера опорной строки

Обратите внимание на разницу в работе команд i и a. Первая вставляет новую строку до указанной, вторая — после.

Замена строк


Команда c позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:
$ sed '3c\This is a modified line.' myfile


Замена строки целиком

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

$ sed '/This is/c This is a changed line of text.' myfile


Замена строк по шаблону

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


Команда y работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:
$ sed 'y/123/567/' myfile


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

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

Вывод номеров строк


Если вызвать sed, использовав команду =, утилита выведет номера строк в потоке данных:
$ sed '=' myfile


Вывод номеров строк

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

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

$ sed -n '/test/=' myfile


Вывод номеров строк, соответствующих шаблону

Чтение данных для вставки из файла


Выше мы рассматривали приёмы вставки данных в поток, указывая то, что надо вставить, прямо при вызове sed. В качестве источника данных можно воспользоваться и файлом. Для этого служит команда r, которая позволяет вставлять в поток данные из указанного файла. При её вызове можно указать номер строки, после которой надо вставить содержимое файла, или шаблон.

Рассмотрим пример:

$ sed '3r newfile' myfile

Вставка в поток содержимого файла

Тут содержимое файла newfile было вставлено после третьей строки файла myfile.

Вот что произойдёт, если применить при вызове команды r шаблон:

$ sed '/test/r newfile' myfile


Использование шаблона при вызове команды r

Содержимое файла будет вставлено после каждой строки, соответствующей шаблону.

Пример


Представим себе такую задачу. Есть файл, в котором имеется некая последовательность символов, сама по себе бессмысленная, которую надо заменить на данные, взятые из другого файла. А именно, пусть это будет файл newfile, в котором роль указателя места заполнения играет последовательность символов DATA. Данные, которые нужно подставить вместо DATA, хранятся в файле data.

Решить эту задачу можно, воспользовавшись командами r и d потокового редактора sed:

$ Sed '/DATA>/ {
r newfile
d}' myfile


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

Как видите, вместо заполнителя DATA sed добавил в выходной поток две строки из файла data.

Итоги


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

На сегодня это всё. В следующий раз поговорим о языке обработки данных awk.

Уважаемые читатели! А вы пользуетесь sed в повседневной работе? Если да — поделитесь пожалуйста опытом.

Проект документации Linux


Информация о LDP
FAQ
Манифест / лицензия
История
Волонтеры / сотрудники
Должностные инструкции
Списки рассылки
IRC
Обратная связь

Автор / внести вклад
Руководство для авторов LDP
Внесите свой вклад / помогите
Ресурсы
Как отправить
Репозиторий GIT
Загрузок
Контакты

Спонсор сайта LDP
Мастерская

LDP Wiki : LDP Wiki — это отправная точка для любой незавершенной работы
Члены | Авторы | Посетители
Документы

HOWTO : тематическая справка
последние обновления | основной индекс | просматривать по категориям
Руководства : более длинные, подробные книги
последние обновления / основной индекс
Часто задаваемые вопросы : Часто задаваемые вопросы
последние обновления / основной индекс
страницы руководства : справка по отдельным командам (20060810)
Бюллетень Linux : Интернет-журнал
Поиск / Ресурсы

Ссылки
Поиск OMF
Объявления / Разное


Обновления документов
Ссылка на HOWTO, которые были недавно обновлены.

.

Примеры манипуляции строкой Bash — длина, подстрока, поиск и замена

В оболочке bash, когда вы используете знак доллара, за которым следует имя переменной, оболочка расширяет переменную ее значением. Эта функция оболочки называется расширением параметров.

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

Эта статья является частью продолжающейся серии руководств по bash. Обратитесь к нашей предыдущей статье о расширении bash {}.

1. Определение длины строки внутри сценария оболочки Bash

 $ {# строка} 

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

 $ кошка len.sh
#! / bin / bash

var = "Добро пожаловать в компьютерную сеть"

эхо $ {# var}

$ ./len.sh
24
 

Чтобы узнать больше о переменных bash, прочтите 6 практических примеров глобальных и локальных переменных Bash.

2. Извлечение подстроки из переменной внутри сценария оболочки Bash

Bash позволяет извлечь подстроку из строки. В следующем примере объясняется, как анализировать n символов, начиная с определенной позиции.

 $ {строка: позиция} 

Извлечь подстроку из $ string в позиции $

 $ {строка: позиция: длина} 

Извлечь $ длину подстроки символов из $ строки, начиная с позиции $. В приведенном ниже примере первый оператор echo возвращает подстроку, начиная с 15-й позиции.Второй оператор echo возвращает 4 символа, начиная с 15-й позиции. Длина должна быть числом больше или равным нулю.

 $ cat substr.sh
#! / bin / bash

var = "Добро пожаловать в компьютерную сеть"

эхо $ {var: 15}
эхо $ {var: 15: 4}

$ ./substr.sh
компьютерщик
фанат
 

Также обратитесь к нашей предыдущей статье, чтобы узнать больше о специальных параметрах $ *, $ @, $ #, $$, $ !, $ ?, $ -, $ _ bash.

3. Кратчайшее совпадение подстроки

Следующий синтаксис удаляет самое короткое совпадение $ substring с начала $ string

 $ {строка # подстрока} 

Следующий синтаксис удаляет самое короткое совпадение с $ substring в строке $

.
 $ {строка% подстрока} 

Следующий пример сценария оболочки объясняет две приведенные выше концепции сопоставления кратчайших подстрок.

 $ cat short.sh
#! / bin / bash

filename = "bash.string.txt"

эхо $ {имя файла # *.}
эхо $ {имя файла%. *}

$ ./shortest.sh
После удаления самого короткого совпадения спереди: string.txt
После удаления самого короткого совпадения сзади: bash.string
 

В первом операторе echo подстрока «*.» Соответствует символам и точке, а # удаляется с начала строки, поэтому подстрока «bash» удаляется. из переменной с именем filename.Во втором операторе эха подстрока ‘. *’ Соответствует подстроке, начинающейся с точки, а% удаляется с конца строки, поэтому он удаляет подстроку ‘.txt’

4. Соответствие самой длинной подстроки

Следующий синтаксис удаляет самое длинное совпадение $ substring с начала $ string

 $ {строка ## подстрока} 

Следующий синтаксис удаляет самое длинное совпадение $ substring в строке $

.
 $ {строка %% подстрока} 

Следующий пример сценария оболочки объясняет две вышеупомянутые концепции соответствия самой длинной подстроки.

 $ cat longest.sh
#! / bin / bash

filename = "bash.string.txt"

echo "После удаления самого длинного совпадения спереди:" $ {filename ## *.}
echo "После удаления самого длинного совпадения сзади:" $ {filename %%. *}

$ ./longest.sh
После удаления самого длинного совпадения спереди: txt
После удаления самого длинного совпадения сзади: bash
 

В приведенном выше примере ## *. удаляет самое длинное совпадение для «*.», которое соответствует «bash.string.» поэтому после разделения он печатает оставшийся текст.И %%. * Удаляет самое длинное совпадение для. * С обратной стороны, которое соответствует «.string.txt», после разделения возвращает «bash».

5. Найти и заменить строковые значения в сценарии оболочки Bash

Заменить только первое совпадение
 $ {строка / шаблон / замена} 

Соответствует шаблону в переменной $ string и заменяет заменой только первое совпадение шаблона.

 $ cat firstmatch.sh
#! / bin / bash

filename = "bash.string.txt"

echo "После замены:" $ {filename / str *./ операции.}

$ ./firstmatch.sh
После замены: bash.operations.txt
 
Заменить все спички
 $ {строка // шаблон / замена} 

Заменяет все совпадения шаблона с заменой.

 $ cat allmatch.sh
#! / bin / bash

filename = "Путь к bash: / bin / bash"

echo "После замены:" $ {filename // bash / sh}

$ ./allmatch.sh
После замены: путь к sh - / bin / sh
 

Что касается поиска и замены, обратитесь к нашим предыдущим статьям — примерам замены sed и поиску и замене Vim.

Заменить начало и конец
 $ {строка / # шаблон / замена} 

Следующий синтаксис заменяется строкой замены, только если шаблон соответствует началу строки $.

 $ {строка /% шаблон / замена} 

Следующий синтаксис заменяется строкой замены, только если шаблон совпадает с концом данной строки $.

 $ кот посматч.ш
#! / bin / bash

filename = "/ корень / администратор / мониторинг / процесс.sh"

echo "Заменено в начале:" $ {filename / # \ / root / \ / tmp}
echo «Заменено в конце»: $ {filename /%.* /. ksh}

$ ./posmatch.sh
Заменено в начале: /tmp/admin/monitoring/process.sh
Заменено в конце: /root/admin/monitoring/process.ksh
 

Рекомендуемая литература

Bash 101 Hacks, Рамеш Натараджан . Большую часть времени я провожу в среде Linux. Так что, естественно, я большой поклонник командной строки и сценариев оболочки Bash. 15 лет назад, когда я работал над разными вариантами * nix, я писал много кода на оболочке C и оболочке Korn.Спустя годы, когда я начал работать в Linux в качестве системного администратора, я в значительной степени автоматизировал все возможные задачи с помощью сценариев оболочки Bash. Основываясь на моем опыте работы с Bash, я написал электронную книгу Bash 101 Hacks, которая содержит 101 практический пример как командной строки Bash, так и сценариев оболочки. Если вы думали об освоении Bash, сделайте себе одолжение и прочтите эту книгу, которая поможет вам взять под контроль командную строку Bash и сценарии оболочки.

Если вам понравилась эта статья, вам тоже может понравиться..



.

Обработка строки Bash

Обработка строки Bash

Введение

С годами оболочка bash приобрела много новых колокольчики и свистки. Некоторые из них очень полезны в сценариях оболочки; но они не кажутся хорошо известными. На этой странице в основном обсуждаются новые те, особенно те, которые изменяют строки. В некоторых случаях они предоставляют полезные альтернативы таким старым резервным серверам, как tr и sed, с приростом скорости. Общая тема — избегать трубопроводов.

В приведенных ниже примерах я предполагаю, что строка — это оболочка переменная, содержащая некоторую символьную строку.или,.) Обратите внимание, что оригинал переменная, строка, не изменяется.

Обычно мы думаем об этом с помощью команды tr:

newstring = ʻecho "$ string" | tr '[a-z]' '[A-Z]' '
newstring = `echo" $ string "| tr '[A-Z]' '[a-z]' '
 
Конечно, это предполагает создание нового процесса. Собственно, как мужчина страница для tr сообщает вам, что это не оптимально; в зависимости от вашего настройки локали, вы можете получить неожиданные результаты. Безопаснее сказать
newstring = ʻecho "$ string" | tr '[: lower:]' '[: upper:]' `
newstring = ʻecho "$ string" | tr '[: upper:]' '[: lower:]' `
 
Использование tr, безусловно, более читабельно; но это также требует много дольше печатать.Как насчет времени выполнения?

Сроки испытаний

Вот фрагмент кода, который сто тысяч раз ничего не делает:
str1 = X

я = 0
время (
пока [$ i -lt 100000]
делать
пусть я ++
сделанный
)
 
На моей машине — сейчас двухъядерный Pentium с тактовой частотой 3 ГГц (6000 bogomips). коробка — это занимает около 1,57 секунды. Это баш накладные расходы на запуск бесполезного цикла. Почти все это «пользователь» время; «системное» время составляет всего несколько десятков миллисекунд.

Теперь добавим строку

str2 = $ {str1 ^^}
 
в цикл сразу после оператора let.Время исполнения прыгает примерно до 2,3 секунды; поэтому выполнение добавленной строки 100000 раз заняло около 0,7 секунды. Это примерно 7 микросекунд на выполнение.

Теперь попробуем поставить линию

str2 = ʻecho "$ str1" | tr '[: lower:]' '[: upper:]' `
 
вместо этого внутри цикла. Время выполнения сейчас колоссальное 1 м 33 с из в реальном времени — но всего 3 секунды пользователя и 7 секунд системного времени! Видимо система выдает и bash, и tr тысячу одна миллисекунда отсекает секунду, а затем берет отпуск, пока наступает следующая круглая миллисекунда.

Если мы попытаемся немного выровнять ситуацию, сделав начальную строку длиннее, мы находим практически такое же время для версии, использующей tr, но примерно на 0,2 секунды дольше, чем раньше, для версии с полной оболочкой, если Преобразуемая строка — «Hello, world!». Ясно, что нам действительно нужен большая строка для точного измерения скорости bash.

Итак, давайте инициализируем исходную строку строкой

str1 = `cat / usr / share / dict / американский-английский`
 
который представляет собой текстовый файл из 931708 символов.Для этого большого файла один цикла через цикл достаточно: требуется bash около 45,7 секунды, все из которых, кроме нескольких миллисекунд, являются «пользовательским» временем. С другой стороны, версия tr занимает всего 0,24 секунды, чтобы обрабатывать большой текстовый файл.

Очевидно, здесь есть компромисс, который зависит от размера строки быть преобразованным. Очевидно, переключение контекста, необходимое для вызова tr — это узкое место при короткой строке; но тр намного эффективнее, чем bash при преобразовании больших строк что быстрее, когда длина строки превышает несколько тысяч символов.Я обнаружил, что моей машине требуется около 1,55 миллисекунд для обработки строки около Длина 4100 символов, независимо от того, какой метод используется. (Об четверть миллисекунды используется системой, когда tr вызывается; предположительно, это время, необходимое для настройки конвейера и переключите контекст.)

sed-подобных Замены

Точно так же вы часто можете заставить bash действовать достаточно, как sed, чтобы избегайте использования трубопровода. Синтаксис
новая строка = $ {старая строка / шаблон / замена}
 
Обратите внимание, что в конце косой черты нет, как в sed или vi: закрывающая фигурная скобка завершает строку подстановки.

Загвоздка в том, что только шаблоны типа оболочки (например, те, которые используются в имени пути) расширение), а не сложные регулярные выражения, распознанные пользователя sed. Кроме того, обычно происходит только одна замена; но ты можно имитировать «глобальную» замену, используя две косые черты перед шаблон:

newstring = $ {oldstring // шаблон / замена}
 
Этот трюк удобно использовать для очистки пользовательского ввода. Например, вы может захотеть преобразовать имя файла в форму, которую безопасно использовать как (часть из) имя переменной оболочки: имена файлов могут содержать дефисы и другие специальные символы, недопустимые в именах переменных, которые могут быть только буквенно-цифровой.Итак, чтобы очистить грязную строку:
чистый = $ {грязный // [-+=.,]]
 
Если бы мы установили dirty = ‘a, b.c = d-e + f’, строка выше преобразует опасные символы для подчеркивания, образуя чистую строку: a_b_c_d_e_f, который можно безопасно использовать в сценарии оболочки.

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

cleaned = $ {грязный // [- + =.,]}
 
эквивалентно
cleaned = `echo $ dirty | sed -e 's / [-+=.,]] // g'`
 
или
cleaned = ʻecho $ грязный | tr -d '+ =., - ''
 
где мы должны поставить дефис последним, чтобы tr не подумал, что это опция.

Будьте осторожны: sed и tr позволяют использовать диапазоны как «A-Z» и «0-9»; но баш требует, чтобы вы либо перечислили их, либо использовали классы символов, такие как [: upper:] или [: digit:] в скобках, определить список шаблонов.

Вы даже можете заставить узор появляться в начале или в конце редактируемая строка, добавив к шаблону префикса # (для начала) или% (для конца).

Подделка имени и dirname

Это использование символа # для обозначения начала редактируемой строки и % в конце, также может использоваться для имитации базового имени и команды dirname в сценариях оболочки:
dirpath = $ {путь% / *}
 
извлекает часть переменной пути с до последняя косая черта; а также
base = $ {путь ## * /}
 
дает часть после последней косой черты. ВНИМАНИЕ : Обратите внимание, что звездочка идет между косой чертой и ##, но после %.

Это потому что

$ {varname # pattern}
 
обрезает самый короткий префикс из содержимого переменной оболочки имя переменной, соответствующее шаблону оболочки; а также
$ {varname ## pattern}
 
обрезает самый длинный префикс , который соответствует шаблону из содержимого переменной оболочки. Точно так же
$ {varname% pattern}
 
обрезает самый короткий суффикс из содержимого переменной оболочки имя переменной, соответствующее шаблону оболочки; а также
$ {varname %% pattern}
 
обрезает самый длинный суффикс , который соответствует шаблону из содержимого переменной оболочки.Вы можете видеть, что общее правило здесь таково: одиночный # или% для соответствия самой короткой части ; или двойной ## или %% для соответствия самая длинная часть.

Но будь осторожен. Если вы просто скармливаете голое имя файла вместо имени пути для dirname вы получаете только точку [.]; но если есть без косых черт в переменной, которую вы обрабатываете с помощью хака над, вы получите имя файла без изменений: потому что в это ничего не удалено. Так что этот трюк не является полной заменой dirname.

Другое использование basename — удаление суффикса из имени файла. Нам часто приходится делать это в сценариях оболочки, когда мы хотим сгенерировать выходной файл с тем же базовым именем, но с другим расширением, чем входной файл. Например, чтобы преобразовать file.old в file.new, вы могли бы использовать

newname = `basename $ oldname .old`.new
 
так что, если вы установили oldname в file.old, newname будет установлено в file.new. Но быстрее сказать
newname = $ {oldname% .old} .new
 
(Обратите внимание, что здесь мы должны использовать операцию%, хотя общая замена для указанного выше базового имени использует ## операция.Это потому, что мы обрезаем суффикс, а не префикс, в данном случае.) Если вы не знали старого расширения файла, вы все еще мог бы заменить это, сказав
newname = $ {oldname%. *}. new
 

Этот способ обрезки префикса или суффикса также полезен для разделение чисел, содержащих десятичную точку, на целое и дробные части. Например, если мы установим DECIMAL = 123.4567, мы можно получить часть перед десятичной как

ЦЕЛОЕ = $ {DECIMAL%. *}
 
и цифры дроби как
ФРАКТ = $ {DECIMAL # *.}
 

Числовые операции

Говоря о цифрах, вы также можете выполнять простую целочисленную арифметику в bash без необходимости вызывать другой процесс, например expr. Помните, что операция let автоматически вызывает арифметические операции. оценка его операндов. Так
пусть сумма = 5 + 2
 
будет хранить 7 в сумме. Конечно, операнды с правой стороны с таким же успехом могут быть переменные оболочки; Итак, если x и y равны числовой, вы могли бы
пусть сумма = x + y
 
который компактнее и быстрее, чем
сумма = ʻexpr $ x + $ y`
 

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

пусть "сумма = х + у"
 
и bash поступит правильно.(Вы должны использовать кавычки, чтобы что let имеет только один аргумент. Если тебе не нравится цитаты, можно сказать
сумма = $ ((х + у))
 
но тогда у вас не может быть пробелов вокруг знака =.)

Этот способ выполнения арифметических операций намного удобнее, чем использование expr — особенно когда вы делаете умножение, поскольку аргументы expr должны разделяться пробелами, поэтому звездочку [*] необходимо заключить в кавычки:

product = ʻexpr $ x \ * $ y`
 
Фу. Довольно уродливо по сравнению с
пусть "product = x * y"
 

Наконец, когда вам нужно увеличить счетчик, вы можете сказать

пусть я ++
 
или
пусть j + = 2
 
что чище, быстрее и удобнее, чем вызов expr.

Подстроки

Помимо усечения префиксов и суффиксов, bash может извлекать подстроки. Чтобы получить 2 символа, следующие за первыми 5 в строке, ты можешь сказать
$ {строка: 5: 2}
 
например.

Это может сэкономить много работы при разборе ответов на shell-скрипт. вопросы. Если сценарий оболочки задает вопрос «да / нет», вам нужно только чтобы проверить первую букву ответа. потом

init = $ {строка: 0: 1}
 
это то, что вы хотите протестировать. (Это дает вам 1 символ, начиная с позиция 0 — другими словами, первый символ строки.)

Если параметр «смещение» равен -1, подстрока начинается с последний символ строки; так

last = $ {строка: -1: 1}
 
дает вам только последний символ. (Обратите внимание на пространство, необходимое для разделения двоеточие со знака минус; это необходимо, чтобы избежать путаницы с последовательность двоеточие-минус, используемая при указании значения по умолчанию.)

Чтобы получить последние 2 символа, вы должны указать

last2 = $ {строка: −2: 2};
 
Обратите внимание, что
penult = $ {строка: −2: 1}
 
дает вам следующий — последний символ.

Замена туалета

Многие вызовы wc можно избежать, особенно когда измеряемый объект мал. Конечно, вам следует избегать работы на файл напрямую с wc в таких конструкциях, как
size = `wc -c somefile`
 
потому что это фиксирует удобное для пользователя повторение имени файла в выход. Вместо этого вы хотите перенаправить ввод в wc:
size = `wc -c
 

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

size = ʻecho -n "$ строка" | туалет -c`
 
- особенно, если строка короткая - потому что bash может сам выполнять работу:
size = $ {# строка}
 

Можно даже сделать bash fake wc -w, если вы не против пожертвовать позиционными параметрами:

установить $ string
nwords = $ #
 

Авторские права © 2011-2012, 2020 Эндрю Т.Молодой


Назад к . . .
главная страница LaTeX

или страница алфавитного указателя

или Домашняя страница GF

или страница обзора веб-сайта

.

Примеры подстрок сценариев Bash

Тесты подстроки Bash

Проверка переменных с помощью команды подстроки

Подстроки и переменные

Подстрока — это в основном последовательность символов в строке. Например, «я — подстрока» — это часть строки «Я — подстрока». Bash дает вам возможность извлекать информацию из этих строк. Ниже приведены некоторые из часто используемых методов извлечения информации:


Длина строки

Мы можем получить длину данной строки, используя следующее: $ {# string } .(Где строка — это имя нашей переменной). Мы можем легко проиллюстрировать это простым скриптом:

  
#! / bin / bash

test = "Добро пожаловать в страну Linux"

echo "Наша переменная test состоит из $ {# test} символов"
   

Когда мы запустим приведенный выше сценарий, мы получим значение длины строки. В этом примере наша фраза «Добро пожаловать в страну Linux» состоит из 28 символов:

  
john @ john-desktop: ~ / scripts $./test11.sh
Наша переменная test состоит из 28 символов.
   

Знание длины строки может быть полезно, когда вам нужно проверить запись. Вы можете запросить, чтобы запись содержала минимум x символов и имела максимальный размер y символов.


Извлечение подстроки из переменной

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

$ {строка: позиция} и $ {строка: позиция: длина}

«строка» указывает имя нашей переменной, а «позиция» — это наша начальная точка, из которой нужно извлечь информацию.Мы можем настроить это дальше, используя параметр «длина». Когда длина используется с позицией, это означает отображение информации, начиная с позиции x для длины y. Мы можем проиллюстрировать это простым скриптом:

  
#! / bin / bash

test = "Добро пожаловать в страну Linux"

echo "Наша переменная test состоит из $ {# test} символов"

test1 = $ {test: 0: 7}
test2 = $ {test: 15: 13}
test3 = $ {test: 0}

echo $ test1
echo $ test2
echo $ test3
   

Вывод из приведенного выше скрипта:

  
Наша переменная test состоит из 28 символов.
Добро пожаловать
Страна Linux
Добро пожаловать в страну Linux
   

Обратите внимание, что наша начальная позиция равна нулю «0».Это самый первый символ нашей строки. Следовательно, если мы посмотрим в позиции «0» на длину 7 символов, мы найдем слово «Добро пожаловать». Точно так же оператор $ {test: 15: 13} возвращает «Land of Linux». Если мы укажем только $ {test: 0}, мы получим полную строку, поскольку позиция «0» является начальной позицией.


Убрать кратчайшее совпадение $ substring с начала или с конца строки

Мы можем использовать синтаксис $ {string # substring} , чтобы удалить самое короткое совпадение $ substring с начала $ string

Чтобы удалить самое короткое совпадение $ substring с обратной стороны $ string мы можем использовать $ {string # substring}

« # » обозначает лицевую сторону, а «% » — оборотную сторону.


Удаляет самое длинное совпадение $ substring в начале или в конце строки

Мы можем использовать синтаксис $ {строка ## подстрока} , чтобы удалить самое длинное совпадение $ подстроки с начала строки $

Чтобы удалить самое длинное совпадение $ подстроки с обратной стороны $ строка , мы можем использовать $ {строка ## подстрока}

« ## » означает переднюю часть, а « %% — заднюю.

Пример:

  
#! / bin / bash

test = "land.of.linux"
echo "Удаление самого короткого совпадения спереди:"
эхо $ {тест # *.}

echo "Собрать самую короткую спичку сзади:"
эхо $ {тест%. *}

echo "Удаление самого длинного спички спереди:"
эхо $ {тест ## *.}

echo "Снимаем самую длинную спичку сзади:"
эхо $ {тест %%. *}
   

Вывод из приведенного выше скрипта:

  
Удаление самого короткого совпадения спереди:
оф.linux
Удаление самого короткого совпадения со спины:
земля
Удаление самого длинного спички спереди:
linux
Снимая самую длинную спичку со спины:
земля
   


Заменить ПЕРВОЕ совпадение $ substring значением замены

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

$ {строка / подстрока / замена}

Пример:

  
#! / bin / bash

test = "один.четыре.три "

echo "Перед заменой: $ test"

echo "После замены: $ {test / fo *. / two.}"
   

Вывод из приведенного выше скрипта:

  
Джон @ Джон-рабочий стол: ~ / scripts $ ./test15.sh
Перед заменой: один, четыре, три
После замены: один, два, три
   

Заменить ВСЕ совпадения $ substring значением замены

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

$ {строка // подстрока / замена}

Пример:

  
#! / bin / bash

test = "один два три один четыре один пять"

echo "Перед заменой: $ test"

echo "После замены: $ {test // one / xxx}"
   

Вывод из приведенного выше скрипта:

  
john @ john-desktop: ~ / scripts $./test16.sh
До замены: один два три один четыре один пять
После замены: ххх два три ххх четыре ххх пять
   

index — Числовая позиция в строке $ первого символа в подстроке $, который соответствует

Следующая команда «index» полезна, поскольку она позволяет вам найти первый символ в подстроке. Команда index сообщит позицию в подстроке, если совпадение найдено, или «0», если совпадение не найдено:

Можно использовать следующий синтаксис: expr index «$ string» $ substring
Сценарий ниже иллюстрирует базовое использование команды «index».

  
#! / bin / bash

test = "AaBbCcDdEeFfGg"

testa = ʻexpr index "$ test" C`
testb = ʻexpr index "$ test" D`
testc = `expr index" $ test "E`
testd = `expr index" $ test "Z`

echo "testa находится в позиции: $ testa"
echo "testb находится в позиции: $ testb"
echo "testc находится в позиции: $ testc"
echo "testd находится в позиции: $ testd"
   

Вывод из приведенного выше скрипта:

  
john @ john-desktop: ~ / scripts $ ./test18.sh
testa находится в позиции: 5
testb находится в позиции: 7
testc находится в позиции: 9
testd находится в позиции: 0
   

Из вышеприведенных выходных данных мы видим, что символ «C» был найден в позиции «5», однако совпадения для символа «Z» не было найдено, что привело к сообщению о позиции «0» (не найдено).


.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *