Получить числовые шаблоны из линии, используя sed / grep - PullRequest
0 голосов
/ 28 января 2020

У меня есть поток строк следующим образом

iter: 0 ival: 0, fcost =               0
iter: 0 ival: 1, fcost =               1
iter: 0 ival: 2, fcost =    0.7115281224
iter: 1 ival: 3, fcost =    0.3990854323
iter: 2 ival: 4, fcost =    0.1486154944
iter: 3 ival: 5, fcost =    0.1353816539
iter: 4 ival: 6, fcost =    0.1013548374
iter: 5 ival: 7, fcost =    0.1856721342

Я хочу получить числовые значения через запятую или пробел из этого потока строк. Примерно так

0 0 0
0 1 1
0 2 0.7115281224
1 3 0.3990854323
2 4 0.1486154944
3 5 0.1353816539
4 6 0.1013548374
5 7 0.1856721342
5 8 0.08961682022
6 9 0.08508076519

Есть ли способ сделать это с помощью grep или sed?

Ответы [ 3 ]

3 голосов
/ 28 января 2020

Если вы уверены, что строки всегда будут следовать этому шаблону, вы можете использовать awk для выбора соответствующих столбцов с учетом правильных разделителей (в данном случае пробел или запятая):

awk -F '[, ]+' '{print $2"\t"$4"\t"$7}' file.txt

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

Вот вывод:

$ cat file.txt 
iter: 0 ival: 0, fcost =               0
iter: 0 ival: 1, fcost =               1
iter: 0 ival: 2, fcost =    0.7115281224
iter: 1 ival: 3, fcost =    0.3990854323
iter: 2 ival: 4, fcost =    0.1486154944
iter: 3 ival: 5, fcost =    0.1353816539
iter: 4 ival: 6, fcost =    0.1013548374
iter: 5 ival: 7, fcost =    0.1856721342
$ awk -F '[, ]+' '{print $2"\t"$4"\t"$7}' file.txt 
0   0   0
0   1   1
0   2   0.7115281224
1   3   0.3990854323
2   4   0.1486154944
3   5   0.1353816539
4   6   0.1013548374
5   7   0.1856721342

Редактировать: как указано в комментариях при печати результата вы можете не захотеть, чтобы разделитель между числами был символом табуляции, поэтому вы можете выбрать другой символ вместо "\ t" в примере выше. Вы также можете использовать что-то вроде:

awk -F '[, ]+' '{print $2,$4,$7}' file.txt

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

Они выводятся , разделенные одиночными пробелами, за которыми следует символ новой строки.

Другой вариант может использовать printf , для более сложных комбинаций.

1 голос
/ 28 января 2020

Вы можете использовать tr , чтобы удалить дополнительный набор символов, которые не являются цифрами, точкой или новой строкой. Второй конвейер до tr для сжатия нескольких пробелов в один может очистить вывод.

echo "iter: 5 ival: 7, fcost =    0.1856721342"|tr -cd " .0123456789\n"|tr -s " "
5 7 0.1856721342
1 голос
/ 28 января 2020

На самом деле, я нашел способ, как мы можем это сделать. Благодаря этому ответу . По сути, мы можем сделать это

sed 's/[^[0-9\.\-]]*/ /g;s/ \+/ /g;s/^ \+\| \+$//g' filename

, где
s/[^[0-9\.\-]]*/ /g: заменяет все нечисловые значения пробелами
s/ \+/ /g: заменяет все пробелы одним пробелом
s/^ \+\| \+$//g : заменяет все предшествующие и конечные пробелы

...