Как извлечь положительные числа в первом столбце из вывода, как в вопросе?
Я запускаю Ubuntu 14.04.1 LTS 64-бит с Bash 4.3.11(1)-release
У меня есть программа под названием harminv
производящая вывод следующим образом:
$ h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 # harminv: 1902 inputs, dt = 0.1 frequency, decay constant, Q, amplitude, phase, error # searching frequency range 0.31831 - 0.477465 # using 200 spectral basis functions, density 6.60692 -2.14026, 3.511909e-05, 30471.5, 0.922444, 1.26783, 1.383955e-06 2.14013, 2.052504e-05, 52134.7, 0.920264, -1.27977, 3.426846e-07 # harminv: 2/6 modes are ok: errs <= 1.000000e-01 and inf * 3.426846e-07 , amps >= 0, 9.000000e-01 * 0.922444, |Q| >= 10
Когда опция -v
(verbose) опущена, я получаю гораздо более аккуратный вывод следующим образом:
- Проблема в разделении строки с помощью команды awk или cut
- grep script - выводит строки одновременно в эхо
- Флокирование filedescriptor в сценарии оболочки
- Поведение задания массива
- Есть ли альтернатива использованию rbash для ограничения пользователя в моей системе?
$ h5totxt hsli0.126.h5 | harminv -t 0.1 -w 2-3 -a 0.9 -f 200 frequency, decay constant, Q, amplitude, phase, error -2.14026, 3.511909e-05, 30471.5, 0.922444, 1.26783, 1.383955e-06 2.14013, 2.052504e-05, 52134.7, 0.920264, -1.27977, 3.426846e-07
Я хотел бы иметь возможность извлекать положительные числа в первом столбце вывода в обоих случаях, но понятия не имею, как это сделать, за исключением того, что я могу использовать sed
или awk
. Я был бы признателен, если бы кто-то указал мне в правильном направлении, и моя цель – записать каждое положительное число, чтобы сделать заговор против какой-либо другой переменной.
- Как я могу использовать arptables для ограничения количества исходящих запросов ARP в секунду?
- Как суммировать вывод двух команд и сохранить их в файле?
- Перенаправление ввода с использованием команды и параметров
- Загрузите другой .bashrc при запуске консоли или термина из командной строки
- изменение нумерации нескольких файлов
- AWK Сравнить столбец 1 из двух файлов Распечатать столбец добавления к третьему на выходе
- Как эскалировать сигнал?
- Получить PID хост-скрипта в bash
2 Solutions collect form web for “Как извлечь положительные числа в первом столбце из вывода, как в вопросе?”
Использование sed
Это напечатает только строки, начинающиеся с положительного числа:
sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p'
В сочетании с одним из ваших конвейеров он будет выглядеть так:
h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p'
Как это работает
-
-n
Это говорит
sed
чтобы не печатать какую-либо строку, если мы явно не попросим ее. -
s/^\([[:digit:]][^ ,]*\).*/\1/p
Это говорит
sed
искать строки, начинающиеся с положительного числа, и печатать только это число.В регулярном выражении
^
соответствует только в начале строки.[[:digit:]]
соответствует любой цифре.[^ ,]*
соответствует тому, что следует за этой цифрой, кроме пробела или запятой. Все они сгруппированы с круглыми скобками, поэтому мы можем ссылаться на число позже как\1
. Затем вся строка заменяется номером, и с опциейp
мы сообщаемsed
распечатать его.Один из них использовался для
[0-9]
для сопоставления цифр. С появлением юникодовых шрифтов это уже не является надежным. Однако выражение[[:digit:]]
является безопасным для Unicode.
Альтернативный вариант с использованием расширенного регулярного выражения
Если вы используете GNU sed (что верно для всех Linux-систем), то параметр -r
можно использовать для получения расширенных регулярных выражений . С расширенным регулярным выражением, parens, используемые для группировки, не нужно избегать:
sed -rn 's/^([[:digit:]][^ ,]*).*/\1/p'
В OSX или других BSD-системах используйте -E
вместо -r
.
Использование awk
Это делает то же самое, но используя awk
:
awk -F, '/^[[:digit:]]/{print $1}'
В сочетании с вашим трубопроводом:
h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | awk -F, '/^[[:digit:]]/{print $1}'
Учитывая ввод, который вы показываете, должно работать следующее:
sed -n 's/[^[:digit:]]/\ &/;/.\n/P'
…или…
sed 's/[^[:digit:]].*//;/./!d'
… с некоторыми sed
s вы могли бы также написать это как …
sed -n 's/[^0-9]/\n&/;/.\n/P'
…или…
sed 's/[^0-9].*//;/./!d'
… и, возможно, даже – в зависимости от вашего набора входных данных – с помощью GNU sed
, например …
sed -n 's/\W/\n&/;/.\n/P'
…или…
sed 's/\W.*//;/./!d'
Поскольку обычный язык – это в основном описание дополнений, вы можете почти всегда поворачивать регулярное выражение на голове. Иногда это делает меньше работы, когда вы делаете.
Поэтому, если вы ищете головку строки для определенного шаблона с неизвестной длиной, проще всего просто искать первую часть строки, которая не соответствует вашему шаблону.
В первом примере выше вставлен символ \n
ewline перед первым нечисловым символом, который он встречает в строке. Затем он проверяет, выполнил ли это (если это сделал) , между вставкой и заголовком строки есть по крайней мере один символ. Если нет, он не печатает, но если это так, он печатает только до \n
ewline, который он вставил.
Следующий пример аналогичен – он просто вырезает самую длинную строку, которую он может, из строки, которая начинается с символа, который не соответствует вашему шаблону, а затем удаляет все пустые строки из вывода.
Остальные – это всего лишь короткие сокращения для того, чтобы сделать что-то большее, чем некоторые sed
s, которые могли бы их интерпретировать, хотя первые два довольно строго придерживаются спецификации синтаксиса POSIX sed
(хотя, возможно, [[:digit:]]
overkill, потому что, насколько я понимаю он, UTF-8 является надмножеством ASCII, и большинство языков, которые не включают арабские цифры, также отличаются от того, в котором я пишу это, чтобы потребовать других модификаций, чтобы сделать эту работу в любом случае) .
Все примеры – в зависимости от реализации и ввода как указано – должны печатать только первую последовательную последовательность совпадений цифр, которые начинаются в начале строки.
Размышляя об этом, хотя, поскольку, похоже, вы все равно разделяете пробелы и запятые – я полагаю, это также можно было бы написать:
sed -n 'y/, -/\n\n\n/;/^[0-9]/P'
… что практически не имеет никакого реального соответствия регулярному выражению – поскольку функция y///
преобразует символы, а не группирует их по шаблонам. Средство регулярного выражения используется только для проверки результата.