Решено: Подстановка в выражение с помощью sed (sed, while)

Модератор: Модераторы разделов

Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Всем привет!
У меня возникла следующая проблема. У меня есть файл Fe.in5.1

5000000 0 0
0 5000000 0
0 0 5000000

Хотелось бы заменить элемент (1.1 это 5000000), (1,2 это 0 и т.д.), (2.1). (2.2), (3.1), (3.2) на значения xn1="0" (1.1), yn1="5000000"(1.2 и т.д), xn2="5000000", yn2="5000000", xn3="-5000000", yn3="5000000", соотвественно.
Для этого пишу следующее.

#!/bin/bash
NZ="2"
i="1"
compaund="Fe"

while [ $i -lt $NZ ]
do
x1=`head -n 1 $compaund.in5.$i | tail -n 1 | gawk '{printf "%10d ",$1}'`
y1=`head -n 1 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

x2=`head -n 2 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$1}'`
y2=`head -n 2 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

x3=`head -n 3 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$1}'`
y3=`head -n 3 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

xn1="0"
yn1="5000000"
xn2="5000000"
yn2="5000000"
xn3="-5000000"
yn3="5000000"

cp $compaund.in5.$i .tmp1

sed "1,1s/$x1/$xn1/" .tmp1 | sed "1,2s/$y1/$yn1/" > .tmp2
cp .tmp2 .tmp1

sed "2,1s/$x2/$xn2/" .tmp1 | sed "2,2s/$y2/$yn2/" > .tmp2
cp .tmp2 .tmp1

sed "3,3s/$x3/$xn3/" .tmp1 | sed "1,2s/$y3/$yn3/" > .tmp2
cp .tmp2 .tmp1
cp .tmp1 $compaund.in5.$i
i=$[$i+1]
done
Но sed делает не то что требуется :) . Помогите пожалуста разобраться.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Что то мне подсказывает что вы слишком сложно подошли к решению задачи, вы бы не могли показать тот вывод который хотите получить в итоге?
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Да, конечно, в итоге должно получится:

0 5000000 0
5000000 5000000 0
-5000000 5000000 5000000

Дело в том что эта чать программы является частью более объёмного кода. Ну это так сказать пока узкое место и его надо как то разрулить. Воть.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
21.11.2007 23:20
Да, конечно, в итоге должно получится:

0 5000000 0
5000000 5000000 0
-5000000 5000000 5000000

А почему нельзя просто распечатывать по шаблону с помощью того же gawk?
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Всмысле распечатать?Вывести на консоль что ли?
Если можно, просьба, за каждым предложением ставить код чтобы мы более предметно разговаривали.
Мне надо чтобы эти изменения затем сохранились в файле.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
21.11.2007 23:43
Всмысле распечатать?Вывести на консоль что ли?

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

P/S Код писать лениво :)
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Я понимаю что любой вывод на консоль можно перенаправить в файл, но задача в том что его именно надо структурного а не абы як перенаправить. Ну так а еси писать лениво код, то смысл что то предлагать?
Вы выдвигаете идею, а кто то другой должен её реализовать? Логично. Но а если у другого не достаточно уровня знаний для реализации вашей идеи, что тогда делать? :drinks:
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
22.11.2007 00:08
Вы выдвигаете идею, а кто то другой должен её реализовать?

Ну вот такой например вариант вас не устроит?

Код:

#!/bin/bash filename1="Fe.in5.1" filename2="temp.txt" gawk 'NR==1{print "0 "$NR" 0"}' $filename1 > $filename2 gawk 'NR==2{print "5000000 "$NR" 0"}' $filename1 >> $filename2 gawk 'NR==3{print "-5000000 5000000 "$NR}' $filename1 >> $filename2
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Добрый день!А вы сами тестили ваш скрипт?
Вот что получается

0 -5000000 0
5000000 5000000 0
-5000000 5000000 5000000

Немного не то что надо...Наверно где то небольшая ошибочка вышла.

Да и можно немного пояснений к коду?
Вот например если немного переделаю ваш код под свой новый шаблон:
Файл называется Fe.in5.1

-5000000 0 0 10000000
0 5000000 0 10000000
0 0 5000000 10000000
3 2 3
51 51
RHO ADD
ATU VAL NODEBUG
NONORTHO

#!/bin/bash
NZ="2"
i="1"
compaund="Fe"

while [ $i -lt $NZ ]
do
x1=`head -n 1 $compaund.in5.$i | tail -n 1 | gawk '{printf "%10d ",$1}'`
y1=`head -n 1 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

x2=`head -n 2 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$1}'`
y2=`head -n 2 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

x3=`head -n 3 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$1}'`
y3=`head -n 3 $compaund.in5.$i |tail -n 1| gawk '{printf "%10d ",$2}'`

xn1="0"; yn1="5000000";
xn2="5000000"; yn2="5000000";
xn3="-5000000"; yn3="5000000";

cp $compaund.in5.$i .tmp1

gawk 'NR==1{print "$xn1 "$NR" 0" " 10000000"}' .tmp1 > .tmp2
gawk 'NR==2{print "$xn2 "$NR" 0" " 10000000"}' .tmp1 >> .tmp2
gawk 'NR==3{print "$xn3 $yn3 "$NR " 10000000"}' .tmp1 >> .tmp2
tail -n 6 .tmp1 >> .tmp2
cp .tmp2 alex.$i.txt

i=$[$i+1]
done

То у меня ничего не получисло.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 15:57
0 -5000000 0
5000000 5000000 0
-5000000 5000000 5000000

Да, конечно проверял.
Вот что у меня получается
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 15:57
Да и можно немного пояснений к коду?

Код:

#!/bin/bash filename1="Fe.in5.1" filename2="temp.txt" # Переменная NR соответсвует номеру обрабатываемой строки # то есть каждая строка соответсвует номеру строки в исходном файле # то что находится в скобках {} является шаблоном для записи в итоговый файл # с помощью переменной NR указываем какой элемент из исходного файла # нужно вставить в итоговый файл и в каком именно месте шаблона # вместо переменной $NR можно указать номера элементов явным образом # то есть $1 для первой строки $2 для второй $3 для третьей gawk 'NR==1{print "0 "$NR" 0"}' $filename1 > $filename2 gawk 'NR==2{print "5000000 "$NR" 0"}' $filename1 >> $filename2 gawk 'NR==3{print "-5000000 5000000 "$NR}' $filename1 >> $filename2
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 15:57
Вот например если немного переделаю ваш код под свой новый шаблон:
Файл называется Fe.in5.1

-5000000 0 0 10000000
0 5000000 0 10000000
0 0 5000000 10000000
3 2 3
51 51
RHO ADD
ATU VAL NODEBUG
NONORTHO

Какой вывод из данного файла вы хотите получить?
Информация в исходном файле статична, или меняется по ходу выполнения программы?
Если информация в исходном файле не статична то подход должен быть несколько другим.
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Прежде чем ответить на ваш вопрос у меня появилась идея.

Ещё раз можно как работает gawk 'NR==1{print "0 "$NR" 0"}' $filename1 > $filename2
Из $filename1 берётся первая строка (так как перед фигурными скобками стоит 1?). Что происходит в 'NR==`? NR присвоивается значение первого поля из $filename1 и подставляется в шаблон {print "0 "$NR" 0"}? Где в этом выражении указано что из $filename1 надо брать значение первого поля?

Теперь как можно реализовать с помощью вашего шаблона чтобы подставлялись переменные а не числа.
То есть чтобы такое gawk 'NR==1{print "0 "$NR" 0"}' $filename1 > $filename2 можно было заменить на

gawk '1{print "$xn1 " "$yn1" " а здесь оставляем как и есть в исходном файле"}' $filename1 > $filename2, аналогияно с остальными 2 строками. Я кончено понимаю что синтаксим моего предложение неправильный, но он отражает логику что мне надо сделать, как его можно подправить?
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 16:56
Ещё раз можно как работает gawk 'NR==1{print "0 "$NR" 0"}' $filename1 > $filename2
Из $filename1 берётся первая строка (так как перед фигурными скобками стоит 1?). Что происходит в 'NR==`? NR присвоивается значение первого поля из $filename1 и подставляется в шаблон {print "0 "$NR" 0"}? Где в этом выражении указано что из $filename1 надо брать значение первого поля?

NR это зарезервированная переменная в gawk обозначающая обрабатываемую строку, при условии что разделитель строк это символ новой строки.
Таким образом выражение NR==1 говорит gawk что следующие действия в скобках {} выполняются относительно первой строки.
Так как номер строки в вашем случае соответсвует номеру поля которое вы хотите перенести в итоговый файл, то соответсвенно мы можем использовать переменную NR в качестве указателя на необходимое поле.

Я вижу что вам нужно написать достаточно сложный скрипт, поэтому лучше воспользуйтесь документацией http://linfoline.homedns.org/awk_baluev/awk_bal_oglav.shtml
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Посмотрел ваш принтскрин...как это у вас получилось настроить консоль так что на заднем фоне видны деревья? Мен тоже такую захотелось :happy: Не подскажете как настроить?

Спасибо за документацию ща сяду изучать.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 17:56
Не подскажете как настроить?

в gnome-terminal

Правка->Текущий профиль->Эффекты
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

АГа...с изменением фона онятно. Ну так а подстановка переменных в gawk?Как можно сделать?
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: Решено: Подстановка в выражение с помощью sed

Сообщение sergeyvp »

Kosya4ok писал(а):
23.11.2007 18:03
Ну так а подстановка переменных в gawk?Как можно сделать?

В данном случае вам видимо прийдётся просто обработать файл не в один приём а в несколько, поэтапно добиваясь необходимого результата.
Вобще подходов для решения данной задачи много и не факт что моё предложение самое правильное. :)
Вставлять переменные непосредственно в выражение видимо не получится, можно только вычислять их внутри выражения формируя необходимые поля.
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

С вашей и Божьей помощью удалось всё ж таки написать скрипт :drinks:


А вот и сам кодец

#!/bin/bash
NZ="52"
i="1"
compaund="Fe"
while [ $i -lt $NZ ]
do
cp $compaund.in5.$i .tmp1
head -n 1 .tmp1 | gawk '{print " 0 " " 5000000 " $3 " 10000000"}' > .tmp2
head -n 2 .tmp1 | tail -n 1 | gawk '{print " 5000000 " " 5000000 " $3 " 10000000"}' >> .tmp2
head -n 3 .tmp1 | tail -n 1 | gawk '{print "-5000000 " " 5000000 " $3 " 10000000"}' >> .tmp2
tail -n 6 .tmp1 >> .tmp2
cp .tmp2 $compaund.in5.$i
echo $i
i=$[$i+1]
done
rm .tmp1
rm .tmp2

Спасибо за помощь sergeyvp!!!
Спасибо сказали:
Kosya4ok
Сообщения: 19
ОС: linux suse, winxp, freebsd

Re: Решено: Подстановка в выражение с помощью sed

Сообщение Kosya4ok »

Слушай а ты не знаешь как можно настроить форум так что бы как то видеть какие тебе со всего форума приходят ответы?

Да и как пометить что данный вопрос разрулен?
Спасибо сказали: