2015-05-20 4 views
3

У меня есть файл sql, который мне нужно изменить, чтобы увеличить размер ID-строки строки на 3. Как я могу увеличить поле ID и сохранить остальную часть строка, как в BASH? Ex:Добавьте число в число, находящееся в строке в BASH

insert into info.names values (35, 'John', 'C', 2); 
insert into info.names values (36, 'Mark', 'C', 1); 
insert into info.names values (37, 'Bob', 'C', 5); 

мне нужно добавить от 3 до 35, 36 и 37, так что они становятся 38,39,40. SO выход будет

insert into info.names values (38, 'John', 'C', 2); 
insert into info.names values (39, 'Mark', 'C', 1); 
insert into info.names values (40, 'Bob', 'C', 5); 

Я хотел бы сделать это в BASH.

Спасибо

+0

только первый номер в строке? –

ответ

2

AWK является более подходящим инструментом для решения этой задачи

awk '{tmp=$5 ;sub(/^\(/, "", tmp); tmp+=3; $5="("tmp","; print $0}' file > file.new && mv file.new file 

Чтобы объяснить, я буду добавлять комментарии и использовать более подробный формат

awk '{ 
     # Capture the 5th field '(35,' into a tmp variable 
     tmp=$5          
     # remove the leading "(" char 
     sub(/^\(/, "", tmp) 
     # add 3 to the tmp value (see note below) 
     tmp+=3 
     # reconstruct the 5th field adding "(" and "," as needed. 
     $5="(" tmp "," 
     # print the whole line 
     print $0 
    }' file > file.new && mv file.new file 
    #  |     |-> if no error (`&&`) overwrite the original file 
    #  |      with the fixed file (not an awk feature) 
    #  |-> write output to tmp file                

Обратите внимание, что после операции sub(/^\(/, "", tmp) значение tmp фактически равно 35, (отметьте , char!). Если задана переменная в числовом контексте (например, +=3), awk обрабатывает только часть номера этого значения, а затем выполняет математическую операцию. Вот почему вы получаете 38, а не 35,3. Линии следующего затем «положить по спине» недостающие «(» и «» символы.

IHTH

+0

Спасибо. Он отлично работал – JohnnyLoo

2

Использование гну-AWK вы можете сделать это:

awk 'BEGIN{ FPAT="[^(]+|\\([0-9]+" } {$2="(" substr($2,2)+3} 1' file.sql 
insert into info.names values (38 , 'John', 'C', 2); 
insert into info.names values (39 , 'Mark', 'C', 1); 
insert into info.names values (40 , 'Bob', 'C', 5); 
+0

[См этого документа для получения подробной информации об использовании FPAT] (https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html) – anubhava

+0

Я заметил, что ваш код подавляет открывающиеся круглые скобки. Пример: вставить в значения info.names (38, 'John', '(C)', 2) ;. Результатом будет: вставить в значения info.names (41, «John», «C»), 2); – JohnnyLoo

0

Спасибо. Я не AWK гуру, так что есть некоторые вещи, которые я не понимаю. Вот что я сделал, но он уверен, много грязнее, чем вы все ответы.

sed -n -r 's/^insert .*\(([0-9]+),.*;/\1/p' Names.sql | while read line; do grep "^insert into info.names values ($line," Names.sql | while read SQLLine; do OLDID=$(echo "$SQLLine" | sed -n -r 's/^insert .*\(([0-9]+),.*;/\1/p'); NEWID=$(expr 2 + $OLDID); sed -n -r "s/(insert into info.names values \()[0-9]+(, .*)/\1$NEWID\2/p" <(echo "$SQLLine"); done; done 

Спасибо вам, ребят

+0

Я думаю, что это было проголосовано, потому что это не отличный ответ. Вероятно, вы указали здесь, чтобы показать, что такое ваш код. Вы можете переместить это как есть, в свой вопрос, чтобы показать, что вы пытались решить проблему. Затем удалите этот ответ, чтобы восстановить потерянные очки репутации. Удачи. – shellter

Смежные вопросы