Как извлечь положительные числа в первом столбце из вывода, как в вопросе?

Я запускаю 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) опущена, я получаю гораздо более аккуратный вывод следующим образом:

 $ 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 . Я был бы признателен, если бы кто-то указал мне в правильном направлении, и моя цель – записать каждое положительное число, чтобы сделать заговор против какой-либо другой переменной.

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/// преобразует символы, а не группирует их по шаблонам. Средство регулярного выражения используется только для проверки результата.

  • чтение из файла и изменение его шаблона в массив?
  • Копирование больших файлов - создает ли пустым файл в пункте назначения?
  • сценарий оболочки для извлечения символов
  • Могу ли я написать вывод команды разницы времени в файл?
  • Как добавить две переменные, переданные в оболочке, которая возвращает число целых чисел?
  • Различные результаты при использовании скрипта или кода вставки
  • Как классифицировать эти строки в этом файле ASCII
  • Для цикла в bash-скриптах, ставя другое значение в команду
  • Запуск сценария bash с php от cron
  • Частота слов в тексте на неанглийском языке: как я могу объединить единичные и множественные формы и т. Д.?
  • Доступ к экранам назад и вперед через скрипт bash
  • Linux и Unix - лучшая ОС в мире.