2015-11-20 4 views
0

Я использую awk для проверки файла свойств и вывода только правильных строк. Я использую несколько разделителей в файле свойств.Проверка файла свойств с awk

Вот пример:

host1:/var/tmp/dir1/,host2:/var/tmp/dir2/ 
host2:/var/tmp/dir2/abc.tgz,host3:/var/tmp/ 

#example of wrong format 
host1::/var/tmp/dir1,host2:/var/tmp/ 
host1:/var/tmp/dir1,:host2:/var/tmp/ 

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

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

#!/usr/xpg4/bin/awk -f 

BEGIN{ 
    FS=":,:" 
} 
{ 
    if ($0 ~/\[(.*)?([^%]*%[^%])(.*)?([^%]*%[^%])(.*)?([^%]*%[^%])]/) { 
     print "validated line " $0 
     next 
    } else { 
     print "error in line " $0 

    }; 

} 

Я что-то упустил? или мое регулярное выражение слишком просто, чтобы захватить линию?

и выход всегда

ошибка в линии host1:/вар/TMP/dir1 /, host2:/вар/TMP/dir2/ ошибка в линии host2:/вар/TMP/dir2/ABC. tgz, host3:/var/tmp/

+1

Вы говорите, что вы получаете сообщение об ошибке. Может быть, вы должны показать это нам? –

+3

Также почему вы сравниваете с 'FS'? –

+2

Какая проверка, точно, вам нужно сделать здесь? Граф полей? Имена полей? Значения полей? –

ответ

1

Ваш подход является ошибочным. Вам нужно написать регулярное выражение для описания формата всей строки. Чтобы мы могли вам помочь, вам нужно описать правильный формат. Предположение было бы что-то вроде этого:

/^[[:alnum:]]+:[[:alnum:]\/\.]+,[[:alnum:]]+:[[:alnum:]\/\.]+$/ 

Где [[:alnum:]]+ означает один или несколько алфавитно-цифровых символов и [[:alnum:]\/\.]+ также соответствует / или ..

Тогда сценарий будет:

/^[[:alnum:]]+:[[:alnum:]\/\.]+,[[:alnum:]]+:[[:alnum:]\/\.]+$/ { 
    print "valid: " $0 
    next 
} 
{ 
    print "invalid: " $0 
} 

Вместо использования [[:alnum:]], вы могли бы обеспечить соблюдение требований, что разделители появляются только в указанном порядке, используя шаблон, например, как это:

/^[^:,]+:[^:,]+,[^:,]+:[^:,]+$/ 
+0

Подход, который позволяет awk разделить поля, является разумным. Особенно, если проверка поля отличается по полю или проще писать в качестве теста для одного поля. –

+0

@Etan. Я вижу, что также может быть полезно проверить поля отдельно, но мне кажется, что сначала должна быть проверена вся строка, иначе невозможно определить, существуют ли разные разделители в правильном порядке. –

+0

Я думаю, это зависит от того, какие возможные правовые значения для них являются ключами и ценностями, но да. В конечном счете все, что не дублирует расщепление/etc. логика конечного потребителя, скорее всего, «сломана». –

1

Чтобы поймать :: или :, (дополнительно он также проверит ,: и ,,), вы можете определить свои FS как [,,] и проверить пустые поля. Упрощенная проверка может быть (с использованием входного файла)

$ awk -F"[:,]" '{for(i=1;i<=NF;i++) 
        if($i=="") 
         print "error on field " i " --> " $0} 
       ' file 
error on field 2 --> host1::/var/tmp/dir1,host2:/var/tmp/ 
error on field 3 --> host1:/var/tmp/dir1,:host2:/var/tmp/ 
1

Я думаю, что вы ищете что-то вроде этого:

BEGIN {FS=":"} 
NF==3 && split($2,a,",")==2 {print "validated line " $0;next} 
{print "error in line " $0}