2013-03-12 2 views
5

У меня есть текстовый файл, содержащий текст и цифры, я хочу использовать Grep, чтобы извлечь только цифры, мне нужно, например, данные файла следующим образом:как извлечь подстроку и номера только с помощью Grep/СЭД

miss rate 0.21 
ipc 222 
stalls n shdmem 112 

Так что скажите, что я хочу только извлечь данные для miss rate, который является 0.21. Как это сделать с помощью grep или sed? Кроме того, мне нужно больше одного номера, а не только после miss rate. То есть, я могу захотеть получить как 0.21, так и 112. Примерный вывод может выглядеть так:

0.21 222 112 

Причина: Мне нужны данные для последующего участка.

+0

Я рекомендую использовать sed вместо grep, если это работает для вас. –

+0

sed также приемлемо, если в этом случае он будет более элегантным. – Hooloovoo

ответ

3

Использование awk вместо:

awk '/^miss rate/ { print $3 }' yourfile 

Чтобы сделать это только с Grep, вам нужно нестандартные расширения, например, здесь с GNU Grep с использованием PCRE (-P) с положительным назад '(? < = ..) и единственный матч (-о):

grep -Po '(?<=miss rate).*' yourfile 
0

Вы можете использовать:

grep -P "miss rate \d+(\.\d+)?" file.txt 

или:

grep -E "miss rate [0-9]+(\.[0-9]+)?" 

Обе эти команды распечатывают miss rate 0.21. Если вы хотите извлечь только номер, почему бы не использовать Perl, Sed или Awk?

Если вы действительно хотите этого избежать, возможно, это сработает?

grep -E "miss rate [0-9]+(\.[0-9]+)?" g | xargs basename | tail -n 1 
1

Если вы действительно хотите использовать только Grep для этого, то вы можете попробовать:

grep "miss rate" file | grep -oe '\([0-9.]*\)' 

Это будет первым найти строку, которая соответствует, а затем выводить только цифры.

Sed может быть немного более читаемым, хотя:

sed -n 's#miss rate ##p' file 
4

Используя специальный взгляд вокруг регулярок трюк \K с двигателем с :

grep -oP 'miss rate \K.*' file.txt 

или :

perl -lne 'print $& if /miss rate \K.*/' file.txt 
+0

Добавлено портативное решение Perl =) –

+0

трюк \ K действительно полезен. Да, я предпочитаю grep делать это, так как я не эксперт в awk, а также проблема с awk - это разделитель полей, так как текст в одном поле может содержать несколько и разных #space, как в 'miss rate XX' и 'stalls total номер XXX ' – Hooloovoo

4

grep -и- cut решение будет выглядеть следующим образом:

, чтобы получить 3-е поле для каждого успешного использования Grep:

grep "^miss rate " yourfile | cut -d ' ' -f 3 

или получить 3-е поле и использование отдыха:

grep "^miss rate " yourfile | cut -d ' ' -f 3- 

Или, если вы используете Баш и «скорость промаха» происходит только один раз в вашем файле вы можете просто сделать:

a=($(grep -m 1 "miss rate" yourfile)) 
echo ${a[2]} 

где ${a[2]} - ваш результат.

Если «пропущенная скорость» встречается больше, чем когда вы можете прокручивать вывод grep только то, что вам нужно. (В Баш)

0

Я считаю

sed 's|[^0-9]*\([0-9\.]*\)|\1 |g' fiilename

будет делать трюк. Однако каждая запись будет на собственной линии, если это нормально. Я уверен, что для sed можно создать список с запятой или пробелом, но я не супермастер всех вещей sed.

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