2009-09-22 5 views
0

У меня есть документ, в котором поля разделены двоеточием (:), где мне нужно время от времени менять второе поле. Документ выглядит следующим образом:sed: поиск и замена меняющегося столбца

name1:UhX.PPFW7$YhPMH0BISY:23490:::::: 
name2:1./0oV$GEs6WJpE$LHXhy:19239:0:29388:2::29302: 
... 

второе поле файла будет меняться время от времени и может содержать пару символов регулярных выражений ($.) И прямой слэш.

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

sed -e "s~^name2:.*:~name2:aTest\$repl.ace:~g" tst 

Данный текст справа от второго столбца теряется:

name2:aTest$repl.ace: 

(то есть '19239: 0: 29388: 2 :: 29302:'). Есть ли способ, которым sed может заменить различный столбец и сохранить остальную часть строки? Или, может быть, есть лучшая программа для этого?

ответ

0

Самый простой способ это изменить. * в вашем регулярном выражении, чтобы соответствовать только тому, что действительно может появиться во втором поле, например:

sed -e "s~^name2:[^:]*:~name2:aTest\$repl.ace:~g" tst 

([^:] * == ничего, что не содержит двоеточие), или:

sed -e "s~^name2:[$./0-9a-zA-Z]*:~name2:aTest\$repl.ace:~g" tst 

([л] * == любого количества символов, перечисленные)

+0

Эй, это здорово. Интересно, возможно ли это в sed. Думал, что я могу взглянуть на более сложную команду. Цените наконечник, Энтони. –

0

Sed Возможно, это не лучший инструмент для этого, потому что, если он действительно не знает о полях. Рассматривают awk (который имеет встроенный в концепцию полей) вместо:

$ awk -F : 'NF>=2{split($0,a,":");a[2]="new sting";printf(a[1]);for(i=2;i<=NF;i++){printf":%s",a[i]};printf("\n");}' <input file> 

или отформатирована для удобства чтения:

awk -F : 'NF>=2 { 
        split($0,a,":"); 
        a[2]="new sting"; 
        printf(a[1]); 
        for(i=2;i<=NF;i++){ 
        printf":%s",a[i] 
        }; 
        printf("\n"); 
       }' <input file> 

Для общности вы можете заменить ":" с FS. Также стоит посмотреть t his join function, который сделает реализацию более чистой, если вы пишете скрипт, а не работаете в командной строке.

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

$2=="string to match" 

или

$2~/regex to match/ 
+0

хех, AWK немного над моей головой в то время, но он работает. Спасибо. –

0

Попробуйте это:

perl -pe 's~^name2:.*?:~name2:aTest\$repl.ace:~g' test 
+0

Начиная с perl - все синтаксисы, которые он использует (я видел), легко запомнить синтаксис. Спасибо за подсказку ennuikiller. –