2016-07-13 2 views
0

Может ли sed обрабатывать замещение и одновременно оценивать выражение, чтобы каким-то образом заменить?sed заменить номер номером-1

Например, я следующая запись в текстовом файле:

##################################### topd Tree1 - Tree14 ####################################### 

По причинам, я не буду, чтобы, номер каждого дерева является N + 1 по отношению к другой схеме нумерации я был используя до сих пор.

Может СЭД (или Util действительно, СЭД просто моя обратиться за находку и заменить операции), найти каждый экземпляр TreeN и заменить их TreeN-1 таким образом, что выше линии будет выглядеть:

##################################### topd Tree0 - Tree13 ####################################### 

(с использованием Ubuntu 12.02, так что почти все, что идет.)

+0

Если ваши столбцы предсказуемы, 'awk' знает математику ... – leekaiinthesky

+0

Да, вы не делаете это с СЕПГ , – 123

+0

Я думаю, что они (есть такой же пробег ### space, topd .... и т. Д. И т. Д., Хотя это кажется менее надежным для меня, что поиск строки? –

ответ

3

Использование Perl

perl -pe 's/Tree\K\d+/$&-1/ge' file 

Выход

##################################### topd Tree0 - Tree13 ####################################### 
+0

с использованием perl кажется самым простым решением. – sjsam

+0

Приятно, я в конечном итоге попробовал это сначала так, как принято в качестве ответа. Чтобы сделать его более информативным, не могли бы вы рассказать о том, какие биты синтаксиса что-то делают? Я могу выделить элементы, но не все. –

+0

@JoeHealey ' \ K' заставляют замену влиять только на правую сторону, поэтому сопоставляются только цифры '\ d +'. '$ &' Соответствует строке. 'G' является глобальным, как и в максимально возможном количестве совпадений. 'e' оценить замену pa rt регулярного выражения, как если бы это была команда. – 123

1

Я хотел бы использовать Perl в этом случае, с модификатором e оценить выражение в замене части:

perl -pe 's/(Tree)(\d+)/$1 . ($2 - 1)/ge' 

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

perl -pe 's/(?<=Tree)(\d+)/$1 - 1/ge' 
+2

Вам также понадобится флаг 'g', а не' # ' – 123

+1

@ 123 Да, я не заметил, что оба номера должны быть уменьшены, отредактированы спасибо! –

0

Вы можете попробовать это;

sed 's/[^0-9,-]*//g' filename | sed -e "s/-/ /g" | awk '{print "##################################### topd Tree"$1-1 " - Tree" $2-1 " #######################################"}' 

awk '{gsub(/Tree/,"Tree ",$0);print $1" "$2" "$3$4-1" "$5" "$6$7-1" "$8}' filename 
+1

Для этого возможно одно awk-решение. Это выглядит так: два 'sed' и 'awk' кажутся излишними – sjsam

0

Использование Gnu AWK ниже

awk '{ 
    for(i=1;i<=NF;i++){ 
    $i ~ /^Tree[[:digit:]]+$/ 
    { 
    n=(gensub(/Tree/,"",1,$i)-1); 
    $i=gensub(/Tree([[:digit:]]+)/,"Tree"n,1,$i); 
    } 
    } 
    print}' file 

будет делать трюк