1 (07.10.2014 12:56:46 отредактировано borisgorbunov)

Есть папка с файлами . В каждом файле есть данные в виде:
------------------------------------------------------------------------------------------------------------------
HOLE = KZK_249 /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZK /* Primary Well Identifier
--------------------------------------------------------------------------------------------------------------------

Нужно подменить значение в строчке HOLE = KZK_249 /*  от знака равно до слэша, на значение из строчки  WELL_BASH = 249KZK /* Primary Well Identifier от знака равно до слэша. Причем в каждом файле значения разные. А их 1000 шт.
Прошу выручайте .  bh

2

Интересный вопрос. Было бы тоже интересно узнать, как это делается...ждём железобетонного суперадминистратора всех Linux-Вселенных, мегагуру bash-scripting'a drBatty.

3 (07.10.2014 14:10:01 отредактировано lone_wolf)

chelovekot пишет:

Интересный вопрос. Было бы тоже интересно узнать, как это делается...ждём железобетонного суперадминистратора всех Linux-Вселенных, мегагуру bash-scripting'a drBatty.

Это 5  bj
Но при этом согласен, drBatty это толковый специалист.

Спросить - стыд минуты, не узнать - стыд всей жизни

4 (07.10.2014 14:40:00 отредактировано i2ks)

часть первая:

a=`grep HOLE file|awk '{print $3}'`
b=`grep WELL_BASH file|awk '{print $3}'`
sed -ri 's/'$a'/'$b'/g' file 

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

как то так:

for i in `cat list`;do sed -ri 's/'$a'/'$b'/g' $i;done

где list список с файлами.
Эту часть не проверял, но первая часть точно работает.

ед-е условие HOLE и WELL_BASH , должны встречаться один раз в файле.

It is good day to die ...
MS Windows 10
Заметки о главном...

5

Причем в каждом файле значения разные., значения a и b надо будет каждый роа обнулять на новые)

p.s. это я что то упустил.

It is good day to die ...
MS Windows 10
Заметки о главном...
i2ks пишет:

Причем в каждом файле значения разные., значения a и b надо будет каждый роа обнулять на новые)

p.s. это я что то упустил.

Ну да в этом и загвоздка.

7 (07.10.2014 15:41:20 отредактировано tmp13)

Я решил извращнуться на awk=)) как обычно=)

tac rep.txt |awk -F[=\ ] '{if(index($0,"WELL_BASH")>0){WB=$4};gsub(/HOLE = [a-Z]*_[0-9]*/,"HOLE = "WB); print $0}'|tac

тут правда с учётом того что вид у HOLE всегда типа
HOLE = [a-Z]*_[0-9]* ну с этим можно поиграться...
Теперь вопрос как прореплейсить файлы если это необходимо=)

8

i2ks пишет:

Причем в каждом файле значения разные., значения a и b надо будет каждый роа обнулять на новые)

p.s. это я что то упустил.

А в чем сложность то? делайте это внутри цикла ab

9 (07.10.2014 15:27:39 отредактировано i2ks)

сделал два файла

$ ls -l
total 8
-rw-rw-r-- 1 526 Oct  7 15:16 file1
-rw-rw-r-- 1 528 Oct  7 15:16 file2

содержание файлов:

$ cat file1
HOLE = KZK_249 /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZK /* Primary Well Identifier

и

$ cat file2
HOLE = KZK_2409 /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZ0K /* Primary Well Identifier

далее в цикле все:

for i in `ls -1`;do  b=`grep WELL_BASH $i|awk '{print $3}'`; a=`grep HOLE $i|awk '{print $3}'`;sed 's/'$a'/'$b'/g' $i;done

результат:

HOLE = 249KZK /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZK /* Primary Well Identifier
HOLE = 249KZ0K /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZ0K /* Primary Well Identifier

как видите все работате.

только у меня просто вывод, а надо еще добавить будет ключик -ri после слова sed

It is good day to die ...
MS Windows 10
Заметки о главном...

10

beliy пишет:

А в чем сложность то? делайте это внутри цикла

ни в чем)

It is good day to die ...
MS Windows 10
Заметки о главном...

11 (07.10.2014 15:46:24 отредактировано tmp13)

Да без sed какай то [CENSORED] типа:

for file in *.txt; do tac $file|awk -F[=\ ] '{if(index($0,"WELL_BASH")>0){WB=$4};gsub(/HOLE = [a-Z]*_[0-9]*/,"HOLE = "WB); print $0}'|tac > new_$file; mv new_$file $file; done

12

Огромное спасибо всем. Беру сие творения на заметку. bs

13

i2ks пишет:

сделал два файла

for i in `ls -1`;do  b=`grep WELL_BASH $i|awk '{print $3}'`; a=`grep HOLE $i|awk '{print $3}'`;sed 's/'$a'/'$b'/g' $i;done

только у меня просто вывод, а надо еще добавить будет ключик -ri после слова sed



for i in `ls -1`;do  b=`grep WELL_BASH $i|awk '{print $3}'`; a=`grep HOLE $i|awk '{print $3}'`;sed -ri 's/'$a'/'$b'/g' $i;done

Вот так ???

14

borisgorbunov пишет:

Вот так ???

да, может на 10ке файлов это проверить. :-)

It is good day to die ...
MS Windows 10
Заметки о главном...

15

borisgorbunov пишет:

for i in `ls -1`;do  b=`grep WELL_BASH $i|awk '{print $3}'`; a=`grep HOLE $i|awk '{print $3}'`;sed -ri 's/'$a'/'$b'/g' $i;done

i2ks пишет:

a=`grep HOLE file|awk '{print $3}'`
b=`grep WELL_BASH file|awk '{print $3}'`
sed -ri 's/'$a'/'$b'/g' file

i2ks пишет:

for i in `ls -1`;do  b=`grep WELL_BASH $i|awk '{print $3}'`; a=`grep HOLE $i|awk '{print $3}'`;sed 's/'$a'/'$b'/g' $i;done

как же иногда хочется ходить по улицам и убивать людей, которые в одной строке мешают sed, grep и awk... хорошо хоть тут tr и cut не понадобились... =)

наиболее разумное решение, ИМХО:

find -type f | while read f; do 
  well_bash=$(sed -rne 's!^WELL_BASH\s=\s(.+)\s/\*.*$!\1!p' $f)
  sed -re 's!^(HOLE\s=\s).+(\s/\*.*)$!\1'"$well_bash"'\2!'  -i  $f
done

ради спортивного интереса, одним sed скриптом:

sed -nre 'H;/WELL_BASH/{x;s!(HOLE\s*=\s*)([^\n]+)(\s*/\*[^\n]*\n.*\nWELL_BASH\s*=\s*)([^\n]+)(\s*/\*[^\n]*\n)!\1\4\3\4\5!;p}' <file>

само собой, у каждого способа есть свои недостатки...

95% процентов проблем находятся между клавиатурой и стулом.

16

Fat-Zer пишет:

как же иногда хочется ходить по улицам и убивать людей, которые в одной строке мешают sed, grep и awk... ...

Ну ты тут не одинок...

17

Да обосраться можно, все такие умные.

It is good day to die ...
MS Windows 10
Заметки о главном...

18

borisgorbunov,
как-то так:

 Консоль:
$ sed -rn 'H;${x;s~(HOLE =)([^/]*)(.*)(WELL_BASH =)([^/]*)~\1\5\3\4\5~;s/\n//;p}' f
HOLE = 249KZK /*
PROJECT = Yark_wdb_int@pnsmos5 /*
DEPTH_BOTTOM = - /* Downhole depth (METRES) DOUBLE
DRILLED_DEPTH = - /* Total Depth - Driller (METRES) DOUBLE
ELEV_MEAS_REF = 181.43 /* Elevation of Measurement Reference (METRES) DOUBLE
FIELD = Jarkeevsky /* Field
LOCATION = Kjizjil-Kjychevskaja /* Location
LOGGED_DEPTH = - /* Total Depth - Logger (METRES) DOUBLE
SYMBOL = CIRCLE /* Symbol
TVD_BOTTOM = - /* True Vertical Depth at well bottom (METRES) DOUBLE
TYPE = SPM /*
WELL_BASH = 249KZK /* Primary Well Identifier

это в предположении, что WELL_BASH всегда идёт  ПОСЛЕ HOLE.
Если ДО, то проще.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

19

chelovekot пишет:

мегагуру bash-scripting'a drBatty.

тут лучше sed.

i2ks пишет:

for i in `cat list`

ну нахрена  жеж?!

while  read line; do …; done <list
i2ks пишет:

ед-е условие HOLE и WELL_BASH , должны встречаться один раз в файле.

в  моём  решении выше может  сколько  угодно раз, меняется первое HOLE на последнее WELL.

tmp13 пишет:

tac rep.txt

тоже интересный вариант.

Fat-Zer пишет:

sed -nre 'H;/WELL_BASH/{x;s!(HOLE\s*=\s*)([^\n]+)(\s*/\*[^\n]*\n.*\nWELL_BASH\s*=\s*)([^\n]+)(\s*/\*[^\n]*\n)!\1\4\3\4\5!;p}' <file>

хм. Опередили.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)