скажем у меня есть SQL.txt
select * from table1;
select a,b,c from table2 where a=1;
Как можно отфильтровать имя таблицы с помощью командыcat SQL.txt|grep
Мой ожидаемый результат:
table1
table2
Я новичок в grep
командовании, буду признателен за любую помощь. Спасибо.
Обновлять
Мне нужно знать, как применять регулярное выражение в grep
команде.
для этого случая я могу написать регулярное выражение: from (.*?)
Проблема в том, что я не знаю, как использовать регулярное выражение с grep
решение1
Grep просто принимает шаблон и файл в качестве аргументов. Как объяснено в man grep
:
GREP(1) User Commands GREP(1)
NAME
grep, egrep, fgrep - print lines that match patterns
SYNOPSIS
grep [OPTION...] PATTERNS [FILE...]
grep [OPTION...] -e PATTERNS ... [FILE...]
grep [OPTION...] -f PATTERN_FILE ... [FILE...]
DESCRIPTION
grep searches for PATTERNS in each FILE. PATTERNS is one or more
patterns separated by newline characters, and grep prints each line
that matches a pattern. Typically PATTERNS should be quoted when grep
is used in a shell command.
Итак, общий формат — grep 'regex' file
. Итак, чтобы использовать ваш пример регулярного выражения, вы должны сделать:
grep 'from (.*?)' file
Однако это не сработает, поскольку grep
используетБазовые регулярные выражения(BRE), которые не обрабатывают скобки как специальные символы 1 и не понимают нежадный *?
оператор (найти самое короткое совпадение). На самом деле вам нужно:
grep 'from [^[:blank:]]' file
Здесь используется класс символов BRE [[:blank:]]
, ноотрицаетего с ^
( [^[:blank:]]
), так что теперь он соответствует любому непробельному символу. Однако это все еще не то, что вам нужно, поскольку grep
вернет все совпадающеелинияа не только часть строки, которая совпала.
Если у вас GNU grep
(по умолчанию в Linux), у вас есть опция -o
, которая указывает grep
возвращать только соответствующую часть:
$ grep -o 'from [^[:blank:]]*' file
from table1;
from table2
Конечно, это все еще не то, что вам нужно, в одном из них есть дополнительный from
, пробел и завершающий ;
. Еще раз, если у вас есть GNU grep
, вы можете использовать PCRE (Perl Compatible Regular Expressions), которые поддерживаютосмотры:
$ grep -oP '(?<=from )\w+' file
table1
table2
Здесь -o
сообщает , grep
что нужно вернуть только соответствующую часть, а -P
включает поддержку PCRE. (?<=from )
называетсяпозитивный взгляд назади означает "соответствовать следующей части, только если соответствует предыдущая часть from
". Наконец, \w
это специальный класс PCRE, который соответствует "символам слова": буквам, цифрам и _
(и немного больше, если используется Unicode). Как объяснено в man perlre
:
\w [3] Match a "word" character (alphanumeric plus "_", plus
other connector punctuation chars plus Unicode
marks)
PCRE также имеют замечательную \K
функцию. Это похоже на ретроспективный просмотр, но по сути означает «игнорировать все, что совпало до этого места». Используя это, мы можем упростить регулярное выражение выше до:
$ grep -oP 'from \K\w+' file
table1
table2
решение2
Попробовал с командой AWK без конвейеризации, протестировал и работал нормально.
awk '{for(i=1;i<=NF;i++){if($i ~ /^table/){gsub(";","",$i);print $i}}}' file
выход
table1
table2