Практическое руководство. Сцепка нескольких строк (руководство по C#)
Объединение подразумевает добавление одной строки к концу другой. Вы можете сцеплять строки с помощью оператора + . Строковые литералы и константы сцепляются во время компиляции, а не во время выполнения. Строковые переменные сцепляются только во время выполнения.
Примеры C# в этой статье выполняются во встроенном средстве выполнения кода и на площадке Try.NET. Нажмите на кнопку Выполнить, чтобы выполнить пример в интерактивном окне. После выполнения кода вы можете изменить его и выполнить измененный код, снова нажав на кнопку Выполнить. Либо в интерактивном окне выполняется измененный код, либо, если компиляция завершается с ошибкой, в интерактивном окне отображаются все сообщения об ошибках компилятора C#.
Строковые литералы
В следующем примере длинный строковый литерал разделяется на более короткие строки для повышения удобочитаемости исходного кода. Код сцепляет строки меньшего размера для создания длинного строкового литерала. Сегменты сцепляются в одну строку во время компиляции. Количество строк не влияет на производительность во время выполнения.
// Concatenation of literals is performed at compile time, not run time. string text = "Historically, the world of data and the world of objects " + "have not been well integrated. Programmers work in C# or Visual Basic " + "and also in SQL or XQuery. On the one side are concepts such as classes, " + "objects, fields, inheritance, and .NET Framework APIs. On the other side " + "are tables, columns, rows, nodes, and separate languages for dealing with " + "them. Data types often require translation between the two worlds; there are " + "different standard functions. Because the object world has no notion of query, a " + "query can only be represented as a string without compile-time type checking or " + "IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " + "objects in memory is often tedious and error-prone."; System.Console.WriteLine(text);
Операторы + и +=
Для сцепки строковых переменных вы можете использовать операторы + или += , интерполяцию строк, а также методы String.Format, String.Concat, String.Join или StringBuilder.Append. Оператор + прост в использовании и позволяет получить интуитивно понятный код. Даже если в одном выражении используется несколько операторов + , содержимое строки копируется только один раз. В следующем коде показаны примеры использования операторов + и += для сцепки строк:
string userName = ""; string dateString = DateTime.Today.ToShortDateString(); // Use the + and += operators for one-time concatenations. string str = "Hello " + userName + ". Today is " + dateString + "."; System.Console.WriteLine(str); str += " How are you today?"; System.Console.WriteLine(str);
Интерполяция строк
В некоторых выражениях строки проще сцепить с помощью интерполяции, как показано в следующем коде:
string userName = ""; string date = DateTime.Today.ToShortDateString(); // Use string interpolation to concatenate strings. string str = $"Hello . Today is ."; System.Console.WriteLine(str); str = $" How are you today?"; System.Console.WriteLine(str);
В операциях сцепки строк компилятор C# обрабатывает строки NULL так же, как пустые строки.
Начиная с C# 10, можно использовать интерполяцию строк для инициализации константной строки, если все выражения, используемые для заполнителей, также являются константными строками.
String.Format
Другие методы сцепки строк: String.Format. Этот метод лучше использовать при создании строки из небольшого числа строк-компонентов.
StringBuilder
В других случаях вы можете сцеплять строки во время цикла и не знать, сколько исходных строк вы сцепляете. При этом фактическое число исходных строк может быть большим. Для этих сценариев предназначен класс StringBuilder. В следующем коде для сцепки строк используется метод Append класса StringBuilder.
// Use StringBuilder for concatenation in tight loops. var sb = new System.Text.StringBuilder(); for (int i = 0; i < 20; i++) < sb.AppendLine(i.ToString()); >System.Console.WriteLine(sb.ToString());
String.Concat или String.Join
Другой вариант объединения строк из коллекции — использовать метод String.Concat. Используйте метод String.Join, если исходные строки должны быть разделены разделителем. Следующий код объединяет массив слов с помощью обоих методов:
string[] words = < "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." >; var unreadablePhrase = string.Concat(words); System.Console.WriteLine(unreadablePhrase); var readablePhrase = string.Join(" ", words); System.Console.WriteLine(readablePhrase);
LINQ и Enumerable.Aggregate
Другой вариант объединения строк из коллекции — использовать LINQ и метод Enumerable.Aggregate. Этот метод объединяет исходные строки с помощью лямбда-выражения. Лямбда-выражение добавляет каждую строку к существующему накоплению. Следующий пример показывает объединение массива слов с добавлением между словами пробела:
string[] words = < "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." >; var phrase = words.Aggregate((partialPhrase, word) =>$" "); System.Console.WriteLine(phrase);
Этот вариант может потребовать большего числа выделений памяти по сравнению с другими методами сцепки коллекций, так как он создает в каждой итерации промежуточную строку. Если оптимизация производительности имеет решающее значение, рассмотрите StringBuilder String.Concat класс или метод или String.Join для объединения коллекции, а не Enumerable.Aggregate .
См. также
- String
- StringBuilder
- Руководство по программированию на C#
- Строки
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Все, что вы хотели знать о подстановке переменных в строках
Переменные в строках можно использовать множеством способов. Я называю это подстановкой переменных, но подразумеваю все ситуации, когда необходимо отформатировать строку с учетом значений переменных. Мне часто приходится объяснять этот момент новичкам, изучающим создание скриптов.
Оригинал этой статьи впервые был опубликован в блоге автора @KevinMarquette. Группа разработчиков PowerShell благодарит Кевина за то, что он поделился с нами этими материалами. Читайте его блог — PowerShellExplained.com.
Объединение
Первый класс методов можно называть объединением. По сути, они принимают несколько строк и объединяют их друг с другом. Объединение уже довольно давно используется для создания форматированных строк.
$name = 'Kevin Marquette' $message = 'Hello, ' + $name
Объединение отлично подходит для ситуаций, когда необходимо добавить всего несколько значений. Однако зачастую применять его довольно сложно.
$first = 'Kevin' $last = 'Marquette'
$message = 'Hello, ' + $first + ' ' + $last + '.'
Этот простой пример читать уже труднее.
Подстановка переменных
В PowerShell есть более простой вариант. Переменные можно задавать непосредственно в строках.
$message = "Hello, $first $last."
Многое зависит от типа кавычек, в которые заключена строка. Строка, заключенная в двойные кавычки, допускает подстановку, а строка с одинарными кавычками — нет. Вы можете выбрать подходящий вариант в зависимости от ситуации.
Подстановка команд
Если вы пытаетесь получить значения свойств в строку, ситуация немного усложняется. Многие новички испытывают с этим проблемы. Позвольте мне сначала показать, что, по их мнению, должно сработать (по идее, все выглядит логично).
$directory = Get-Item 'c:\windows' $message = "Time: $directory.CreationTime"
Казалось бы, вы должны получить CreationTime из $directory , но вместо этого вы получаете в качестве значения Time: c:\windows.CreationTime . Причина в том, что подстановка такого типа распознает только базовую переменную. Она интерпретирует точку как часть строки, поэтому не сопоставляет значение на более глубоких уровнях.
Выходит так, что при помещении в строку этот объект предоставляет строку в качестве значения по умолчанию. Некоторые объекты вместо этого предоставляют имя типа, например System.Collections.Hashtable . Это то, на что нужно обратить внимание.
PowerShell позволяет выполнять команды внутри строки с помощью специального синтаксиса. Это позволяет получить свойства этих объектов и выполнить любую другую команду для получения значения.
$message = "Time: $($directory.CreationTime)"
Этот подход отлично подходит для определенных ситуаций, но в некоторых случаях может оказаться таким же неудобным, как объединение при наличии нескольких переменных.
Выполнение команды
Команды можно выполнять внутри строки. Хотя так можно делать, мне это не нравится. Код быстро становится перегруженным, и его трудно отлаживать. Я либо использую команду и сохраняю ее результат в переменную, либо использую строку форматирования.
$message = "Date: $(Get-Date)"
Строка форматирования
.NET позволяет отформатировать строки, с которыми довольно легко работать. Сначала позвольте продемонстрировать статический метод, после чего я покажу, как сделать то же самое с помощью ярлыка PowerShell.
# .NET string format string [string]::Format('Hello, .',$first,$last) # PowerShell format string 'Hello, .' -f $first, $last
В этом случае строка анализируется на наличие токенов и , а затем этот номер используется для выбора среди предоставленных значений. Если вы хотите повторить одно значение в строке, можно повторно использовать его номер.
При таком подходе чем сложнее строка, тем больше значений будет получено.
Форматирование значений в виде массивов
Если строка форматирования слишком длинная, можно сначала поместить значения в массив.
$values = @( "Kevin" "Marquette" ) 'Hello, .' -f $values
Это не сплаттинг, поскольку я передаю весь массив, но идея аналогична.
Расширенное форматирование
Я намеренно использовал для вызова .NET, так как для этой платформы уже хорошо задокументировано множество вариантов форматирования. Существуют встроенные способы форматирования различных типов данных.
"" -f (Get-Date) "Population " -f 8175133
20211110 Population 8,175,133
Рассматривать я их не буду, лишь упомяну, что это очень эффективный механизм форматирования, который вы можете использовать при необходимости.
Объединение строк
Иногда требуется сцепить список значений вместе. Это можно сделать с помощью оператора -join . Он даже позволяет указать символ для объединения строк.
$servers = @( 'server1' 'server2' 'server3' ) $servers -join ','
Если с помощью -join необходимо объединить несколько строк без разделителя, необходимо указать пустую строку » . Но если нужно сделать только это, существует более быстрый вариант.
[string]::Concat('server1','server2','server3') [string]::Concat($servers)
Также стоит отметить, что с помощью оператора -split строки можно разделить.
Join-Path
Этот командлет часто бывает неудобен, но он отлично подходит для создания пути к файлу.
$folder = 'Temp' Join-Path -Path 'c:\windows' -ChildPath $folder
Самое замечательное в нем то, что он правильно обрабатывает обратные косые черты, когда собирает значение воедино. Это особенно важно, если вы принимаете значения от пользователей или файлов конфигурации.
Он также прекрасно работает с Split-Path и Test-Path . Я также рассказываю о нем в публикации о чтении и сохранении в файлы.
Строки как массивы
Прежде чем продолжить, я должен упомянуть о добавлении строк. Помните, что строка представляет собой обычный массив символов. При добавлении нескольких строк в одну каждый раз создается новый массив.
Взгляните на этот пример.
$message = "Numbers: " foreach($number in 1..10000)
Он выглядит очень простым, но на самом деле при каждом добавлении строки в $message создается полностью новая строка. Для этого выделяется память, в нее копируются данные, а старая строка удаляется. Ничего особенного, если такая операция выполняется лишь несколько раз, но в случае цикла, подобного этому, это может быть проблемой.
StringBuilder
Класс StringBuilder также очень часто используется для создания больших строк из множества строк меньшего размера. Его популярность связана с тем, что он просто собирает все добавленные в него строки, а затем сцепляет их в конце при извлечении значения.
$stringBuilder = New-Object -TypeName "System.Text.StringBuilder" [void]$stringBuilder.Append("Numbers: ") foreach($number in 1..10000) < [void]$stringBuilder.Append(" $number") >$message = $stringBuilder.ToString()
Опять же, именно поэтому я использую .NET. Пользуюсь я им нечасто, но знать о его существовании будет не лишним.
Разграничение с помощью фигурных скобок
Этот метод используется для объединения суффикса с другими данными в строке. Иногда у переменной отсутствует четкая граница слова.
$test = "Bet" $tester = "Better" Write-Host "$test $tester $ter"
Благодарю /u/real_parbold за эту идею.
Вот альтернатива данному подходу.
Write-Host "$test $tester $($test)ter" Write-Host " ter" -f $test, $tester
Лично я использую для этого строку форматирования, но знать о такой возможности будет не лишним на тот случай, если вам она где-то встретится.
Токены для поиска и замены
Хотя большая часть этих функций призвана снизить потребность в развертывании собственного решения, их можно применять и в тех случаях, когда необходимо заменить строки в больших файлах шаблонов.
Предположим, что вы извлекли шаблон из файла, который содержит большой объем текста.
$letter = Get-Content -Path TemplateLetter.txt -RAW $letter = $letter -replace '#FULL_NAME#', 'Kevin Marquette'
У вас может быть много токенов для замены. Хитрость заключается в том, чтобы использовать особый токен, который легко найти и заменить. Я обычно использую специальный символ на обоих концах, чтобы его было проще отличить.
Недавно я обнаружил новый подход для решения этой задачи. Так как это довольно распространенная схема, я не стану вдаваться в дальнейшие подробности в этом разделе.
Замена нескольких токенов
Если у меня есть список токенов, которые нужно заменить, я использую более универсальный подход. Я помещаю их в хэш-таблицу и перебираю их методом итерации, чтобы выполнить замену.
$tokenList = @ < Full_Name = 'Kevin Marquette' Location = 'Orange County' State = 'CA' >$letter = Get-Content -Path TemplateLetter.txt -RAW foreach( $token in $tokenList.GetEnumerator() ) < $pattern = '##' -f $token.key $letter = $letter -replace $pattern, $token.Value >
При необходимости эти токены можно загрузить из файла JSON или CSV.
Метод ExpandString класса ExecutionContext
Существует отличный способ, который заключается в том, чтобы определить строку подстановки с помощью одинарных кавычек, а затем развернуть переменные. Взгляните на этот пример.
$message = 'Hello, $Name!' $name = 'Kevin Marquette' $string = $ExecutionContext.InvokeCommand.ExpandString($message)
При вызове .InvokeCommand.ExpandString в текущем контексте выполнения для подстановки используются переменные в текущей области. Ключевым моментом здесь является то, что $message можно определить заранее, когда переменные еще даже не существуют.
Немного дополнив этот код, можно обеспечить повторное выполнение этой замены для различных значений.
$message = 'Hello, $Name!' $nameList = 'Mark Kraus','Kevin Marquette','Lee Dailey' foreach($name in $nameList)
Развивая эту идею, можно импортировать большой шаблон электронной почты из текстового файла. Я благодарю Марка Крауса за это предложение.
Оптимальный вариант для конкретной ситуации
Мне нравится подход со строками форматирования. Я применяю его для более сложных строк или при наличии нескольких переменных. Но для коротких строк подойдет любой из описанных методов.
Что-нибудь еще?
Я лишь вкратце затронул эту тему. Я надеюсь, что вы сможете двигаться дальше, узнав для себя что-то новое.
Ссылки.
Если вы хотите узнать больше о методах и функциях, которые позволяют интерполяции строк, см. в следующем списке справочной документации.
- Объединение использует оператор сложения
- Переменная и подстановка команд соответствуют правилам кавыкания
- Форматирование использует оператор форматирования
- Присоединение строк использует оператор соединения и ссылки Join-Path , но вы также можете прочитать о Join-String
- Массивы документируются в массивах About
- StringBuilder — это класс .NET с собственной документацией
- Фигурные скобки в строках также рассматриваются в правилах кворирования
- Замена маркера использует оператор замены
- В этом методе $ExecutionContext.InvokeCommand.ExpandString() содержится справочная документация по API .NET
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как передать данные программе через скрипт bash?
Не совсем понимаю как можно пережать данные в программу через скрипт bash? У меня есть программа на С++, которая принимает на вход две строки разделанные ‘\n’.
#!/bin/bash ./a.out & echo "abcd" & echo "abcd" echo "end prog"
Отслеживать
задан 24 мар 2020 в 6:41
Vlad Stepanov Vlad Stepanov
157 2 2 серебряных знака 8 8 бронзовых знаков
А это оринально использовать выполнение в фоне. Красиво разложенные грабли.
24 мар 2020 в 17:17
Я думаю — это опечатка. На самом деле, TS имел в виду: ./a.out && echo «abcd» && echo «abcd» Это даёт логическое выражение. По правилам оптимизации, сначала вычислится самый левый опреанд и только если он даст «Истина» будет вычисляться второй, ну и так далее. Это известный трюк на shell.
Как в параметрах скрипта передать две строки
Работа с переменными и/или подстановка их значений $ То же самое, что и $parameter, т.е. значение переменной parameter. В отдельных случаях, при возникновении неоднозначности интерпретации, корректно будет работать только такая форма записи: $ . Может использоваться для конкатенации (слияния) строковых переменных.
your_id=$-on-$ echo "$your_id" # echo "Старый \$PATH = $PATH" PATH=$:/opt/bin #Добавление /opt/bin в $PATH. echo "Новый \$PATH = $PATH"
$ , $ Если параметр отсутствует, то используется значение по-умолчанию.
echo $ # Вывод результата работы команды `whoami`, если переменная $username не установлена.
| Формы записи $ и $ в большинстве случаев можно считать эквивалентными. Дополнительный символ : имеет значение только тогда, когда parameter определен, но имеет «пустое» (null) значение. |
#!/bin/bash username0= # переменная username0 объявлена, но инициализирована "пустым" значением. echo "username0 = $" # Вывод после символа "=" отсутствует. echo "username1 = $" # Переменная username1 не была объявлена. # Выводится имя пользователя, выданное командой `whoami`. username2= # переменная username2 объявлена, но инициализирована "пустым" значением. echo "username2 = $" # Выводится имя пользователя, выданное командой `whoami`, поскольку #+здесь употребляется конструкция ":-" , а не "-". exit 0
Параметры по-умолчанию очень часто находят применение в случаях, когда сценарию необходимы какие либо входные аргументы, передаваемые из командной строки, но такие аргументы не были переданы.
DEFAULT_FILENAME=generic.data filename=$ # Если имя файла не задано явно, то последующие операторы будут работать #+ с файлом "generic.data". #
см. так же Пример 3-4, Пример 28-2 и Пример A-7. Сравните этот подход с методом списков and list , для задания параметров командной строки по-умолчанию . $ , $ Если значения параметров не задананы явно, то они принимают значения по-умолчанию. Оба метода задания значений по-умолчанию до определенной степени идентичны. Символ : имеет значение только когда $parameter был инициализирован «пустым» (null) значением, [1] как показано выше.
echo $ # Переменная "username" принимает значение, возвращаемое командой `whoami`.
$ , $ Если параметр имеет какое либо значение, то используется alt_value, иначе — null («пустая» строка). Оба варианта до определенной степени идентичны. Символ : имеет значение только если parameter объявлен и «пустой», см. ниже.
echo "###### \$ ########" echo a=$ echo "a = $a" # a = param2= a=$ echo "a = $a" # a = xyz param3=123 a=$ echo "a = $a" # a = xyz echo echo "###### \$ ########" echo a=$ echo "a = $a" # a = param5= a=$ echo "a = $a" # a = # Вывод отличается от a=$ param6=123 a=$ echo "a = $a" # a = xyz
$ , $ Если parameter инициализирован, то используется его значение, в противном случае — выводится err_msg. Обе формы записи можно, до определенной степени, считать идентичными. Символ : имеет значение только когда parameter инициализирован «пустым» значением, см. ниже.
Пример 9-13. Подстановка параметров и сообщения об ошибках
#!/bin/bash # Проверка отдельных переменных окружения. # Если переменная, к примеру $USER, не установлена, #+ то выводится сообщение об ошибке. : $ $ $ $ echo echo "Имя машины: $HOSTNAME." echo "Ваше имя: $USER." echo "Ваш домашний каталог: $HOME." echo "Ваш почтовый ящик: $MAIL." echo echo "Если перед Вами появилось это сообщение," echo "то это значит, что все критические переменные окружения установлены." echo echo # ------------------------------------------------------ # Конструкция $ так же выполняет проверку #+ наличия переменной в сценарии. ThisVariable=Value-of-ThisVariable # Обратите внимание, в строковые переменные могут быть записаны #+ символы, которые запрещено использовать в именах переменных. : $ echo "Value of ThisVariable is $ThisVariable". echo echo : $ # Если ZZXy23AB не инициализирована, #+ то сценарий завершается с сообщением об ошибке. # Текст сообщения об ошибке можно задать свой. # : $ # То же самое: dummy_variable=$ # dummy_variable=$ # # echo $ >/dev/null echo "Это сообщение не будет напечатано, поскольку сценарий завершится раньше." HERE=0 exit $HERE # Сценарий завершит работу не здесь.
Пример 9-14. Подстановка параметров и сообщение о «порядке использования»
#!/bin/bash # usage-message.sh : $ # Сценарий завершит свою работу здесь, если входные аргументы отсутствуют, #+ со следующим сообщением. # usage-message.sh: 1: Порядок использования: usage-message.sh ARGUMENT echo "Эти две строки появятся, только когда задан аргумент в командной строке." echo "Входной аргумент командной строки = \"$1\"" exit 0 # Точка выхода находится здесь, только когда задан аргумент командной строки. # Проверьте код возврата в обеих случаях, с и без аргумента командной строки. # Если аргумент задан, то код возврата будет равен 0. # Иначе -- 1.
Подстановка параметров и/или экспансия. Следующие выражения могут служить дополнениями оператора match команды expr, применяемой к строкам (см. Пример 12-6). Как правило, они используются при разборе имен файлов и каталогов.
- $ и $ возвращает количество аргументов (позиционных параметров) .
- Для массивов, $ и $ возвращает количество элементов в массиве.
Пример 9-15. Длина переменной
#!/bin/bash # length.sh E_NO_ARGS=65 if [ $# -eq 0 ] # Для работы скрипта необходим хотя бы один входной параметр. then echo "Вызовите сценарий с одним или более параметром командной строки." exit $E_NO_ARGS fi var01=abcdEFGH28ij echo "var01 = $" echo "Length of var01 = $" echo "Количество входных параметров = $" echo "Количество входных параметров = $" exit 0
$ , $
Удаляет из переменной $var наименьшую/наибольшую подстроку, совпадающую с шаблоном $Pattern. Поиск ведется с начала строки $var.
# Функцмя из сценария "days-between.sh". # Удаляет нули, стоящие в начале аргумента-строки. strip_leading_zero () # Ведущие нули, которые согут находиться в номере дня/месяца, # лучше удалить val=$ # В противном случае Bash будет интерпретировать числа return $val # как восьмеричные (POSIX.2, sect 2.9.2.1). >
echo `basename $PWD` # Имя текущего рабочего каталога. echo "$" # Имя текущего рабочего каталога. echo echo `basename $0` # Имя файла-сценария. echo $0 # Имя файла-сценария. echo "$" # Имя файла-сценария. echo filename=test.data echo "$" # data # Расширение файла.
Удаляет из переменной $var наименьшую/наибольшую подстроку, совпадающую с шаблоном $Pattern. Поиск ведется с конца строки $var.
Bash версии 2 имеет ряд дополнительных возможностей.
Пример 9-16. Поиск по шаблону в подстановке параметров
#!/bin/bash # Поиск по шаблону в операциях подстановки параметров # ## % %%. var1=abcd12345abc6789 pattern1=a*c # * (символ шаблона), означает любые символы между a и c. echo echo "var1 = $var1" # abcd12345abc6789 echo "var1 = $" # abcd12345abc6789 (альтернативный вариант) echo "Число символов в $ = $" echo "pattern1 = $pattern1" # a*c (между 'a' и 'c' могут быть любые символы) echo echo '$ =' "$" # d12345abc6789 # Наименьшая подстрока, удаляются первые 3 символа abcd12345abc6789 ^^^^^^ |-| echo '$ =' "$" # 6789 # Наибольшая подстрока, удаляются первые 12 символов abcd12345abc6789 # ^^^^^^ |----------| echo; echo pattern2=b*9 # все, что между 'b' и '9' echo "var1 = $var1" # abcd12345abc6789 echo "pattern2 = $pattern2" echo echo '$ =' "$" # abcd12345a # Наименьшая подстрока, удаляются последние 6 символов abcd12345abc6789 # ^^^^^^^^^ |----| echo '$ =' "$" # a # Наибольшая подстрока, удаляются последние 12 символов abcd12345abc6789 # ^^^^^^^^^ |-------------| # Запомните, # и ## используются для поиска с начала строки, # % и %% используются для поиска с конца строки. echo exit 0
Пример 9-17. Изменение расширений в именах файлов :
#!/bin/bash # rfe # --- # Изменение расширений в именах файлов. # # rfe old_extension new_extension # # Пример: # Изменить все расширения *.gif в именах файлов на *.jpg, в текущем каталоге # rfe gif jpg ARGS=2 E_BADARGS=65 if [ $# -ne "$ARGS" ] then echo "Порядок использования: `basename $0` old_file_suffix new_file_suffix" exit $E_BADARGS fi for filename in *.$1 # Цикл прохода по списку имен файлов, имеющих расширение равное первому аргументу. do mv $filename $$2 # Удалить первое расширение и добавить второе, done exit 0
Подстановка значений переменных / Замена подстроки
Эти конструкции перекочевали в Bash из ksh .
Подстанавливается значение переменной var, начиная с позиции pos.
Первое совпадение с шаблоном Pattern, в переменной var замещается подстрокой Replacement.
Если подстрока Replacement отсутствует, то найденное совпадение будет удалено.
Глобальная замена. Все найденные совпадения с шаблоном Pattern, в переменной var, будут замещены подстрокой Replacement.
Как и в первом случае, если подстрока Replacement отсутствует, то все найденные совпадения будут удалены.
Пример 9-18. Поиск по шаблону при анализе произвольных строк
#!/bin/bash var1=abcd-1234-defg echo "var1 = $var1" t=$ echo "var1 (все, от начала строки по первый символ \"-\", включительно, удаляется) = $t" # t=$ то же самое, #+ поскольку оператор # ищет кратчайшее совпадение, #+ а * соответствует любым предшествующим символам, включая пустую строку. # (Спасибо S. C. за разъяснения.) t=$ echo "Если var1 содержит \"-\", то возвращается пустая строка. var1 = $t" t=$ echo "var1 (все, начиная с последнего \"-\" удаляется) = $t" echo # ------------------------------------------- path_name=/home/bozo/ideas/thoughts.for.today # ------------------------------------------- echo "path_name = $path_name" t=$ echo "Из path_name удален путь к файлу = $t" # В данном случае, тот эе эффект можно получить так: t=`basename $path_name` # t=$; t=$ более общее решение, #+ но имеет некоторые ограничения. # Если $path_name заканчивается символом перевода строки, то `basename $path_name` не будет работать, #+ но для данного случая вполне применимо. # (Спасибо S.C.) t=$ # Тот же эффект дает t=`dirname $path_name` echo "Из path_name удалено имя файла = $t" # Этот вариант будет терпеть неудачу в случаях: "../", "/foo////", # "foo/", "/". # Удаление имени файла, особенно когда его нет, #+ использование dirname имеет свои особенности. # (Спасибо S.C.) echo t=$ echo "Из $path_name удалены первые 11 символов = $t" t=$ echo "Из $path_name удалены первые 11 символов, выводится 5 символов = $t" echo t=$ echo "В $path_name подстрока \"bozo\" заменена на \"clown\" = $t" t=$ echo "В $path_name подстрока \"today\" удалена = $t" t=$ echo "В $path_name все символы \"o\" переведены в верхний регистр, = $t" t=$ echo "Из $path_name удалены все символы \"o\" = $t" exit 0
$
Если в переменной var найдено совпадение с Pattern, причем совпадающая подстрока расположена в начале строки (префикс), то оно заменяется на Replacement. Поиск ведется с начала строки
Если в переменной var найдено совпадение с Pattern, причем совпадающая подстрока расположена в конце строки (суффикс), то оно заменяется на Replacement. Поиск ведется с конца строки
Пример 9-19. Поиск префиксов и суффиксов с заменой по шаблону
#!/bin/bash # Поиск с заменой по шаблону. v0=abc1234zip1234abc # Начальное значение переменной. echo "v0 = $v0" # abc1234zip1234abc echo # Поиск совпадения с начала строки. v1=$ # abc1234zip1234abc # |-| echo "v1 = $v1" # ABCDE1234zip1234abc # |---| # Поиск совпадения с конца строки. v2=$ # abc1234zip123abc # |-| echo "v2 = $v2" # abc1234zip1234ABCDEF # |----| echo # ---------------------------------------------------- # Если совпадение находится не с начала/конца строки, #+ то замена не производится. # ---------------------------------------------------- v3=$ # Совпадение есть, но не в начале строки. echo "v3 = $v3" # abc1234zip1234abc # ЗАМЕНА НЕ ПРОИЗВОДТСЯ! v4=$ # Совпадение есть, но не в конце строки. echo "v4 = $v4" # abc1234zip1234abc # ЗАМЕНА НЕ ПРОИЗВОДТСЯ! exit 0
$ , $
Поиск по шаблону всех, ранее объявленных переменных, имена которых начинаются с varprefix .
xyz23=whatever xyz24= a=$ # Подстановка имен объявленных переменных, которые начинаются с "xyz". echo "a = $a" # a = xyz23 xyz24 a=$ # То же самое. echo "a = $a" # a = xyz23 xyz24 # Эта возможность была добавлена в Bash, в версии 2.04.