2015-11-12 4 views
0

У меня есть данныеAWK Различные проверки на другой линии Начало

с

90|1234|10:50|Y 
91|1234|JOHN|[email protected]|alert 
92|1234|Student|MIB Alerts 

Примечание: $ 2 является ключевой ценностью & он имеет какое-то значение в следующей логике

Я хочу сделать другую проверку

for line starting with 90, NF=4, $2 Numeric, $3 Time, $4 Y/N 
for line starting with 91, NF=5, $2 Non Empty, $3 Email ID 
for line starting with 92, NF=4, $2 Numeric 

В итоге я разделил файлы в соответствии с 90, 91 & 92 значения $ 1 старт

с использованием

grep "^90" filename | awk -F '|' 'NF == 4 && $2 ~ /^[0-9]*$/ && $3 ~ /^[0-9]{2}:[0-9]{2} $/ && $4 ~/^[YN]$/' >> file90.txt 
grep "^91" filename | awk -F '|' 'NF == 5 && $2 ~ /^[0-9]*$/ && !length($3) && $4 ~ /^[[:alnum:]_.][email protected][[:alnum:]_]+[.][[:alnum:]]+$/' >> file91.txt 
grep "^92" filename | awk -F '|' 'NF == 4 && $2 ~ /^[0-9]*$/' >> file92.txt 

затем

cat file92.txt >> file91.txt 
cat file91.txt >> file90.txt 

С некоторыми изменениями эта модель работает для меня, но она имеет 2 недостатка:

  1. Это изменяет файл как 90 остается сверху, а затем 91, а затем 92 [В записи входящих файлов могут входить любые шаблоны, 91 может наступить]
  2. несколько файлов, Разделяет & присоединиться
  3. Я чувствую, я использую Grep понапрасну

Может кто-то поможет мне в этом в одном сценарии AWK или заявление

+4

Добавить '$ 1 ==" 90 "' к первому условию, $ 1 == "91" ко второй и т. Д. – Barmar

+0

вы скажете if ($ 1 == "90") {...} else if ($ 1 == "91") {...} – Ashish

+0

и завернуть все ваши тесты в 1 awk-программу. Удачи. – shellter

ответ

3

Добавить условия на $1 для каждой проверки ,

awk -F'|' ' 
    $1 == "90" && NF == 4 && $2 ~ /^[0-9]*$/ && $3 ~ /^[0-9]{2}:[0-9]{2} $/ && $4 ~/^[YN]$/ { print } 
    $1 == "91" && NF == 5 && $2 ~ /^[0-9]*$/ && !length($3) && $4 ~ /^[[:alnum:]_.][email protected][[:alnum:]_]+[.][[:alnum:]]+$/ { print } 
    $1 == "92" && NF == 4 && $2 ~ /^[0-9]*$/ { print }' filename > result.txt 
+0

Спасибо :), я не знал, что решение было таким прямым – Ashish

2

Я настоятельно рекомендую вам определить функцию для каждого положительного теста вы хотите сделать на поле, а затем просто использовать (отрицается при необходимости) функции в каждом правиле проверки:

$ cat tst.awk 
function isNumeric(val) { return (val == val+0)    } 
function isTime(val)  { return (val ~ /^[0-9]{2}:[0-9]{2}$/) } 
function isEmpty(val) { return (val == "")     } 
function isYN(val)  { return (val ~ /^[YN]$/)    } 
function isEmailId(val) { return (val ~ /^[[:alnum:]_.][email protected][[:alnum:]_]+[.][[:alnum:]]+$/) } 

BEGIN { FS="|" } 
($1==90) && (NF==4) && isNumeric($2) && isTime($3) && isYN($4) 
($1==91) && (NF==5) && !isEmpty($2) && isEmailId($3) 
($1==92) && (NF==4) && isNumeric($2) 

$ awk -f tst.awk file 
90|1234|10:50|Y 
92|1234|Student|MIB Alerts 

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

Вы понимаете, почему я говорю только для определения «положительных функций»? Потому что, если вы определяете:

function isNonEmpty(val) { return (val != "")     } 

, а затем некоторое время в будущем вам нужен тест на пустой вы в конечном итоге писать:

.... && !isNonEmpty(..) ... 

т.е. вы ввести двойное отрицание. Не пишите отрицательный код, а затем вы не можете получить страшный двойной отрицательный код.

+1

Спасибо ED, Это действительно помогает мне в решении более сложных проблем +1 – Ashish

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