Создание нескольких входных файлов с помощью sed в цикле for

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

Solve[x^2+5^a==0,x]>>a.out 

То, что я хотел бы сделать, – создать несколько файлов сценариев, изменив значение «a», скажем от 1 до 10, и назовите каждый файл соответствующим значением «a», например 1.m, 2.m и т. Д. Для этого , Я попытался использовать команду sed в цикле for следующим образом:

 for ((i=1; i<=10; i++)); do sed 's/a/i/' <am >im; done 

так что для каждого фиксированного значения i оно заменило бы «a» на числовое значение и создало новый файл с именем «i.m». Однако над строкой создается один файл сценария с именем im, а 'a' заменяется на 'i'. Какие-либо предложения ?

2 Solutions collect form web for “Создание нескольких входных файлов с помощью sed в цикле for”

Сценарии оболочки содержат много литеральных строк (имена команд, имена файлов и т. Д.), Поэтому использование значения переменной требует, чтобы символ явно указывал, что это ссылка на переменную: расширение параметра состоит из $ за которым следует имя переменной (в ее простейшая форма). В общем, вам нужны двойные кавычки вокруг подстановки переменных . Внутри одинарных кавычек переменные вообще не расширяются ( $ inside '…' просто означает для себя). Таким образом:

 for ((i=1; i<=10; i++)); do sed "s/a/$i/" <am >"$im" done 

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

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

 for ((i=1; i<=10; i++)); do echo "a=$i;" >"$im" cat am >>"$im" done 

Оператор перенаправления >> добавляет к существующему файлу, в отличие от > который усекает файл, если он существует.

Я думаю, было бы ошибкой звонить так много sed где только один будет делать. sed к славе – это способность эффективно перебирать входные данные и изменять их на другой выход, но также может легко обрабатывать несколько выходов. Здесь, например, это POSIX-портативный (и гораздо более эффективный) переписывающий цикл for :

 echo "Solve[x^2+5^a==$((a=0)),x]>>a.out" >/tmp/im ###create file + init $a until [ "$((a+=1))" -gt 10 ] ###iterate + test do printf "h;s/a/$a/gpw /tmp/$am\ng;" ###push new sed command done| sed -nf - /tmp/im ###read + apply commands head /tmp/[0-9].m /tmp/10.m ###print results 

sed может прочитать свой скрипт из stdin и применить его к именованному файлу – вот что sed -nf - /tmp/im . Он также может одновременно выводить свой вывод на stdout и выводить свой вывод на один или несколько именованных файлов. Когда цикл оболочки работает, он печатает строки в sed которые, когда они закончены, составляют:

 h;s/a/1/gpw /tmp/1.m g;h;s/a/2/gpw /tmp/2.m g;h;s/a/3/gpw /tmp/3.m g;h;s/a/4/gpw /tmp/4.m g;h;s/a/5/gpw /tmp/5.m g;h;s/a/6/gpw /tmp/6.m g;h;s/a/7/gpw /tmp/7.m g;h;s/a/8/gpw /tmp/8.m g;h;s/a/9/gpw /tmp/9.m g;h;s/a/10/gpw /tmp/10.m g 

Что говорит sed

  1. Перезапишите свой старый буфер с копией своего буфера редактирования.
  2. g lobally s/// ubstitute каждое вхождение буквы a в свой буфер редактирования с любым текущим значением для переменной оболочки $a .
  3. В то же время оба p pinting результаты этой s/// ubstitution на stdout и приводят результаты в файл с именем /tmp/$am где $a является итерируемым.
  4. И последний раз в буфер хранения, перезаписывая буфер редактирования.

sed будет применять эту последовательность для каждой строки в названном входном файле. При первом вызове он усекает каждый из его названных файлов, но после этого добавит каждое действие к каждому выходному файлу в последовательности. Поскольку у меня есть только одна строка в im , однако, sed prints:

 Solve[x^2+5^1==0,x]>>1.out Solve[x^2+5^2==0,x]>>2.out Solve[x^2+5^3==0,x]>>3.out Solve[x^2+5^4==0,x]>>4.out Solve[x^2+5^5==0,x]>>5.out Solve[x^2+5^6==0,x]>>6.out Solve[x^2+5^7==0,x]>>7.out Solve[x^2+5^8==0,x]>>8.out Solve[x^2+5^9==0,x]>>9.out Solve[x^2+5^10==0,x]>>10.out 

И head , читая из каждого из вновь созданных десяти файлов в /tmp , печатает:

 ==> /tmp/1.m <== Solve[x^2+5^1==0,x]>>1.out ==> /tmp/2.m <== Solve[x^2+5^2==0,x]>>2.out ==> /tmp/3.m <== Solve[x^2+5^3==0,x]>>3.out ==> /tmp/4.m <== Solve[x^2+5^4==0,x]>>4.out ==> /tmp/5.m <== Solve[x^2+5^5==0,x]>>5.out ==> /tmp/6.m <== Solve[x^2+5^6==0,x]>>6.out ==> /tmp/7.m <== Solve[x^2+5^7==0,x]>>7.out ==> /tmp/8.m <== Solve[x^2+5^8==0,x]>>8.out ==> /tmp/9.m <== Solve[x^2+5^9==0,x]>>9.out ==> /tmp/10.m <== Solve[x^2+5^10==0,x]>>10.out 
  • Escape [в grep
  • я хочу напечатать строку, которая начинается с словесного слова, а в остальных записях печатается только одно поле
  • Преобразование xlsx в xls в сценарии оболочки Linux
  • BASH: как Grep и отображает набор значений
  • Solaris / bin / sh поиск файла ведет себя иначе, чем выполнение файла. Зачем?
  • Домашний путь пользователей в сценарии bash
  • Создание моей собственной функции cp в bash
  • Чтение двух списков, содержащих имена файлов
  • Делайте работу «читать», когда не фокусируетесь на терминале
  • Как работает эта команда sed?
  • В команде не работает
  • Linux и Unix - лучшая ОС в мире.