2015-07-12 2 views
1

Учитывая следующую строку текста:шаблон с помощью Grep или AWK

abc/xyz-ibl.txt-234- "simple", /* col */ 

Как я могу извлечь xyz-ibl.txt и simple из приведенного выше текста с использованием регулярных выражений. Имя файла может быть любым, но у него всегда есть расширение .txt, а simple также может быть чем угодно, но за ним всегда следует , /* col */.

ответ

1

Это позволит получить вам имя файла:

grep -oP "\b[^/]*\.txt" 

И это поможет вам simple:

grep -oP '(?<=")[^"]*(?="\s*,\s*/\*\s*col\s*\*/)' 

И это поможет вам обоим:

grep -oP '\b[^/]*\.txt|(?<=")[^"]*(?="\s*,\s*/\*\s*col\s*\*/)' 

Пример:

s='abc/xyz-ibl.txt-234- "simple", /* col */' 
echo "$s" |grep -oP "\b[^/]*\.txt" 
echo "$s" |grep -oP '(?<=")[^"]*(?="\s*,\s*/\*\s*col\s*\*/)' 

Выход:

xyz-ibl.txt 
simple 

Примечание: -P для Perl регулярного выражения.

EDIT:

По вашему комментарию, если вы хотите, чтобы извлечь их, если только оба они соответствуют, то лучше использовать sed чем grep.

Использование sed с расширенными регулярными выражениями:

echo "$s" |sed -nr 's#.*/(\b[^/]+\.txt).*"([^"]*)*"\s*,\s*/\*\s*col\s*\*/#\1\n\2#p' 

Использованием Основных регулярных выражений:

echo "$s" |sed -n 's#.*/\([^/]*\.txt\).*"\([^"]*\)*"[[:space:]]*,[[:space:]]*/\*[[:space:]]*col[[:space:]]*\*/#\1\n\2#p' 
+0

Невозможно объединить эти 2 регулярных выражения в одном? – Shahzad

+0

@Shahzad да, добавлено еще одно grep с двумя слитыми. – Jahid

+0

Работает, но все равно работает как OR. Можно ли заставить его работать как AND, где оба выражения должны совпадать в одно и то же время. – Shahzad

0

Чтобы вернуть только строки, содержащую .txt использования awk с -F, OFS затем трубой для grep инвертировать:

awk -F'/|.txt|"' 'BEGIN { OFS = ".txt" } { print $2," "$4} | grep -v ',' 

Результат:

xyz-ibl.txt simple 
+0

Даже если нет совпадения, он печатает .txt. Фактически, вход поступает из другого grep, который должен быть доставлен для дальнейшего анализа. Это означает, что существует несколько строк, которые не содержат этот шаблон. – Shahzad

0

Вот решение, используя AWK

awk '{ match ($0, /\/([^.]+)(.txt)-.*"([^"]+)"/, fields); printf("%s%s %s\n", fields[1], fields[2], fields[3]); }' 

выше не считает стиль C комментария в конце. Следующее.

awk '{ match ($0, /\/([^.]+)(.txt)-.*"([^"]+)", \/\* col \*\//, fields); printf("%s%s %s\n", fields[1], fields[2], fields[3]); }' 
Смежные вопросы