Как заменить один символ, чтобы получить много строк в оболочке?

Я могу найти много вопросов с ответами в другом направлении, но, к сожалению, не в том, в котором я хотел бы получить замену: я намереваюсь заменить символ , такой как # , в строке , такой как test#asdf , последовательностью , например {0..10} чтобы получить последовательность строк , в этом примере test0asdf test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf .

Я пытался, от других:

  • echo '_#.test' | tr # {0..10} echo '_#.test' | tr # {0..10} (выбрасывает использование)
  • echo '_#.test' | sed -r 's/#/{0..10}/g' echo '_#.test' | sed -r 's/#/{0..10}/g' (возвращает _{0..10}.test )
  • echo '_#.test' | sed -r 's/#/'{0..10}'/g' echo '_#.test' | sed -r 's/#/'{0..10}'/g' (работает первый раз, потом я получаю sed: can't read (...) no such file or directory )

Какой рабочий подход к этой проблеме?

Отредактируйте, поскольку я пока не могу комментировать: я должен использовать # в строке, в которой этот символ должен быть заменен, как строка, переданная из другой программы. Я мог сначала заменить это другим символом все же.

6 Solutions collect form web for “Как заменить один символ, чтобы получить много строк в оболочке?”

Оператор zsh {0..10} (теперь также поддерживается несколькими другими shellми, включая bash ) – это просто еще одна форма расширения скобок в стиле csh .

Он раскрывается оболочкой перед вызовом команды. Команда не видит эти {0..10} .

С tr '#' {0..10} (в кавычках # как в противном случае он обрабатывается оболочкой как начало комментария), tr заканчивается при вызове с помощью (“tr”, “#”, “0”, “1 “, …,” 10 “) в качестве аргументов и tr не ожидает столько аргументов.

Здесь вы хотели бы:

 echo '_'{0..10}'.test' 

чтобы echo передавалось “_0.test”, “_1.test”, …, “_10.test” в качестве аргументов.

Или, если вы хотите, чтобы # был переведен в этот оператор {0..10} , преобразуйте его в код оболочки для оценки:

 eval "$(echo 'echo _#.test' | sed 's/#/{0..10}/')" 

где передается eval echo _{0..10}.test качестве аргументов.

(не то, чтобы я рекомендовал делать что-то подобное).

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

 str='test#asdf' IFS='#' read -r prefix suffix < <<"$str" names=( "$prefix"{0..10}"$suffix" ) declare -p names 
 declare -a names='([0]="test0asdf" [1]="test1asdf" [2]="test2asdf" [3]="test3asdf" [4]="test4asdf" [5]="test5asdf" [6]="test6asdf" [7]="test7asdf" [8]="test8asdf" [9]="test9asdf" [10]="test10asdf")' 

Вы должны использовать # ? Может быть, вы могли бы использовать %d ?

 $ for i in {1..10}; do printf "_%d.test " "$i"; done _1.test _2.test _3.test _4.test _5.test _6.test _7.test _8.test _9.test _10.test 

Первый # начинает комментарий. Таким образом, вы должны избежать этого с \ .

Во-вторых, используйте цикл for .

Вот ваше решение:

 for i in {1..10} do echo '_#.test' | tr \# $i done 

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

 for i in {1..10} do echo '_#.test' | sed "s/#/$i/" done 

Я бы сделал это с расширением параметра :

 $ var='test#asdf' $ for i in {1..10}; do echo "${var/\#/"$i"}"; done test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf 

Расширение ${ parameter / pattern / string }

  • принимает разложение $ parameter (в нашем случае $var ) и
  • заменяет первое вхождение pattern (экранированный #/# имеет особое значение в контексте «заменить в начале строки», которого мы хотим избежать) на
  • string (в нашем случае "$i" )

В качестве альтернативы вы можете заменить # на %d и использовать его как строку формата для printf

 printf "${var/\#/%d}\\n" {1..10} 

Если вам нужно расширение строки, то этого достаточно:

 echo 'test'{1..11}'asdf' test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf test11asdf 

Если вам нужно заменить # в нескольких строках, вы можете использовать позиционные аргументы:

 $ set -- test#asdf{,,,,,,,,,,} $ printf '%s ' "$@"; echo test#asdf test#asdf test#asdf test#asdf test#asdf test#asdf test#asdf test#asdf test#asdf $ j=0; for i do echo "${i//#/"$((j+=1))"}"; done test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf test11asdf 
  • Как напечатать количество рисунков в каждой строке?
  • Как извлечь строки из исходного файла со ссылочным файлом, добавить в файл результатов?
  • Передача файла с локального компьютера на удаленный сервер
  • Как передать значение переменной из функции в вызывающую процедуру в Shellscript
  • Использовать ли `xargs` аргументы, которые он получает каждый вместо каждых аргументов` -n`?
  • Хотите скачать резервную копию моей базы данных через скрипт bash
  • Как дождаться всех файлов и скопировать в каталог
  • Как извлечь число из строки ниже, которая является выводом команды?
  • Использование переменной * в сценарии оболочки для ссылки на все файлы в папке
  • Является ли использование исходного файла, уже полученного в родительском скрипте, необязательным?
  • это нормально, чтобы запустить работу cron с тем же временем?
  • Linux и Unix - лучшая ОС в мире.