Я хочу, отфильтровывают строки, имеющие то же число-> то же число
из этого текста
[325194/777232]/var/cache/apt/srcpkgcache.bin: 100% extents: 5 -> 1 [ OK ]
[325195/777232]/var/cache/apt/pkgcache.bin: 100% extents: 4 -> 1 [ OK ]
[325255/777232]/var/cache/man/de/index.db: 100% extents: 2 -> 2 [ OK ]
[325521/777232]/var/log/syslog: 100% extents: 7 -> 1 [ OK ]
[325525/777232]/var/log/lastlog: 100% extents: 2 -> 2 [ OK ]
[325531/777232]/var/log/syslog.1: 100% extents: 5 -> 1 [ OK ]
[325572/777232]/var/log/kern.log: 100% extents: 6 -> 1 [ OK ]
[325589/777232]/var/log/auth.log: 100% extents: 3 -> 1 [ OK ]
[325621/777232]/var/log/faillog: 100% extents: 2 -> 2 [ OK ]
[325625/777232]/var/log/wtmp: 100% extents: 3 -> 1 [ OK ]
[325627/777232]/var/log/kern.log.1: 100% extents: 2 -> 1 [ OK ]
[325644/777232]/var/log/cups/access_log.1: 100% extents: 2 -> 1 [ OK ]
[325810/777232]/var/log/auth.log.1: 100% extents: 2 -> 1 [ OK ]
Для получения строк, что имеет same_number-> шаблон same_number :
grep -E '([[:digit:]]+)[[:blank:]]+->[[:blank:]]+\1[[:blank:]]'
-E
включает ДО (Расширенное регулярное выражение)
([[:digit:]]+)
соответствия одна или несколько цифр и вставляет полученные соответствия группы 1
[[:blank:]]+
один или несколько горизонтальных пробелов
->
, соответствия буквально
\1
отсылают к первым полученным соответствиям группы
[[:blank:]]
пробел после этого
, можно использовать подобную логику с другими популярными относящимися к обработке текстов инструментами/языками как sed
, awk
, perl
.
Для получения строк, которые не имеют шаблон, только добавьте -v
опция:
grep -vE '([[:digit:]]+)[[:blank:]]+->[[:blank:]]+\1[[:blank:]]'
Пример:
% cat file.txt
[325194/777232]/var/cache/apt/srcpkgcache.bin: 100% extents: 5 -> 1 [ OK ]
[325195/777232]/var/cache/apt/pkgcache.bin: 100% extents: 4 -> 1 [ OK ]
[325255/777232]/var/cache/man/de/index.db: 100% extents: 2 -> 2 [ OK ]
[325521/777232]/var/log/syslog: 100% extents: 7 -> 1 [ OK ]
[325525/777232]/var/log/lastlog: 100% extents: 2 -> 2 [ OK ]
[325531/777232]/var/log/syslog.1: 100% extents: 5 -> 1 [ OK ]
[325572/777232]/var/log/kern.log: 100% extents: 6 -> 1 [ OK ]
[325589/777232]/var/log/auth.log: 100% extents: 3 -> 1 [ OK ]
[325621/777232]/var/log/faillog: 100% extents: 2 -> 2 [ OK ]
[325625/777232]/var/log/wtmp: 100% extents: 3 -> 1 [ OK ]
[325627/777232]/var/log/kern.log.1: 100% extents: 2 -> 1 [ OK ]
[325644/777232]/var/log/cups/access_log.1: 100% extents: 2 -> 1 [ OK ]
[325810/777232]/var/log/auth.log.1: 100% extents: 2 -> 1 [ OK ]
% grep -E '([[:digit:]]+)[[:blank:]]+->[[:blank:]]+\1[[:blank:]]' file.txt
[325255/777232]/var/cache/man/de/index.db: 100% extents: 2 -> 2 [ OK ]
[325525/777232]/var/log/lastlog: 100% extents: 2 -> 2 [ OK ]
[325621/777232]/var/log/faillog: 100% extents: 2 -> 2 [ OK ]
% grep -vE '([[:digit:]]+)[[:blank:]]+->[[:blank:]]+\1[[:blank:]]' file.txt
[325194/777232]/var/cache/apt/srcpkgcache.bin: 100% extents: 5 -> 1 [ OK ]
[325195/777232]/var/cache/apt/pkgcache.bin: 100% extents: 4 -> 1 [ OK ]
[325521/777232]/var/log/syslog: 100% extents: 7 -> 1 [ OK ]
[325531/777232]/var/log/syslog.1: 100% extents: 5 -> 1 [ OK ]
[325572/777232]/var/log/kern.log: 100% extents: 6 -> 1 [ OK ]
[325589/777232]/var/log/auth.log: 100% extents: 3 -> 1 [ OK ]
[325625/777232]/var/log/wtmp: 100% extents: 3 -> 1 [ OK ]
[325627/777232]/var/log/kern.log.1: 100% extents: 2 -> 1 [ OK ]
[325644/777232]/var/log/cups/access_log.1: 100% extents: 2 -> 1 [ OK ]
[325810/777232]/var/log/auth.log.1: 100% extents: 2 -> 1 [ OK ]
Можно сделать это с GNU Awk (gawk
).
Принятие входа хранится в MY_FILE
и Вы хотите видеть только строки с теми же числами, это могло бы быть похожим на это:
gawk '{match($0,/([[:digit:]]+)\s*->\s*([[:digit:]])+/,M);if(M[1]==M[2])print$0}' MY_FILE
Если Вы хотите удалить строки с равными количествами и показать только тем, которые имеют различные числа, просто заменяют ==
с !=
:
gawk '{match($0,/([[:digit:]]+)\s*->\s*([[:digit:]])+/,M);if(M[1]!=M[2])print$0}' MY_FILE
Объяснение:
gawk
выполнит инструкции в фигурных скобках для каждой строки, которые являются:
match($0, /([[:digit:]]+)\s*->\s*([[:digit:]])+/, M) ;
if(M[1] == M[2]) print$0
Это означает, соответствуйте регулярному выражению ([[:digit:]]+)\s*->\s*([[:digit:]])+
против целой строки ($0
) и храните объект соответствия в переменной M
.
Затем сравните содержание группы 1 и 2 соответствия (число прежде и после стрелки соответственно) и распечатайте целую строку, если это равно (если Вы используете ==
) или отличающийся (если Вы используете !=
).
Вам действительно не нужно соответствие регулярного выражения, если Ваши данные структурированы как разграниченные поля.
В Вашем случае, ->
всегда появляется как 5-е разграниченное пробелом поле, таким образом, достаточно протестировать значения 4-го и 6-го:
awk '$6 != $4' file
Если положение ->
варьируется, затем Вы могли сделать что-то как
awk '{for(i=1;i<NF;i++) if ($i == "->" && $(i-1) != $(i+1)) {print; break}}' file
или разделение строка на ->
сначала и затем разделение части любая сторона на пробеле и тесте последнее поле первой части против первого поля второго:
awk -F' -> ' '{
n=split($1,a,/[ \t]+/); split($2,b,/[ \t]+/); if(b[1] != a[n]) print
}' file