Вывести только цифры linux

Как отфильтровать только цифры из строки в сценариях оболочки bash?

Я хочу измерить температуру Raspberry pi 3 и соответственно изменить цвет фона текста. По мере того, как идет код, мы можем распечатать температуру на дисплее. Теперь я хочу отфильтровать только цифры из текста. И используйте это в условии if. Исходный код выглядит так:

#!/bin/bash measurement() < i=1 echo "Reading Temperature" echo "Updating time is set to $1" while [ $i -eq 1 ]; do temp="$(vcgencmd measure_temp | cut -d= -f 2 | cut -d\' -f 1)" tput setaf 7 if [[ $temp -ge 70 ]]; then tput setab 1 echo -ne "Temperature = $temp\r" elif [[ $temp -ge 65 && $temp -le 69 ]]; then put setab 3 echo -ne "Temperature = $temp\r" elif [[ $temp -ge 60 && $temp -le 64 ]]; then tput setab 2 echo -ne "Temperature = $temp\r" elif [[ $temp -ge 55 && $temp -le 59 ]]; then tput setab 6 echo -ne "Temperature = $temp\r" else tput setab 4 echo -ne "Temperature = $temp\r" fi sleep $1 done >if [ -n "$1" ]; then sleep_time=$1 measurement $sleep_time else read -p "Enter the Update Time: " sleep_time measurement $sleep_time fi 

2 ответа

Типичными инструментами для удаления нежелательных символов из текста являются tr и sed (и управление переменными непосредственно в оболочке с помощью таких конструкций, как $ , но если вы не хотите использовать специальные расширения оболочки, которые предоставляют ограниченные возможности). Для вашего варианта использования проще всего сделать:

temp="$(vcgencmd measure_temp | tr -cd '[[:digit:]]')" 

Это просто удаляет ( -d ) все символы, которые не являются ( -c ) членом класса символов digit .

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

Источник

How do I fetch only numbers in grep?

Here «-o» is used to only output the matching segment of the line, rather than the full contents of the line.

The squiggly brackets (e.g. < and >) indicate the number of instances of the match. requires that the previous character or character class must occur at least once, but no more than four times.

@FractalSpace when have the constrain of repeating at least one time in 8 <1,>, the -o option might not necessary, since repeating at least one time, by definition remove the empty output?

You can use RE bracket expression [:digit:] specified by section 9.3.5 of POSIX standard , in combination with -o flag to print only matching «words»

You can use Perl style regular expressions as well

-P Interpret PATTERNS as Perl-compatible regular expressions (PCREs).

-o Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.

Читайте также:  Linux run desktop file

grep -o will print only the matching part of the line. Otherwise grep will print any lines with the pattern.

I would use curl to access your file locally or remotely, then I would grep lines with numbers wrapped in (: ) then cut those pieces off and write to file

the accepted answer ignores there could be numbers in the previous lines of the file, it does work for the example data, but what if the file was remote?

curl file:///home/$USER/Public/input.txt | grep -o '(:.*)' | cut -d ":" -f 2 | cut -d ")" -f 1 > output.txt 

In this example output.txt in your current folder will be written over, we are accessing input.txt from your Public folder.

curl https://yoursite.com/Public/input.txt | grep -o '(:.*)' | cut -d ":" -f 2 | cut -d ")" -f 1 > output.txt 

Источник

sed, capture only the number

I cannot think on a one-liner, so this is my approach:

while read line do grep -Po '(?<=A=)\d+' <<< "$line" || echo "0" done < file 

I am using the look-behind grep to get any number after A= . In case there is none, the || (else) will print a 0 .

This prepends A=0 to the line before substituting.

Ah, I like your solution better. Is the \< thing making sure you get the last 'A='? What does it actually do?

@cluracan, We always get the last A= because .* is greedy. That's why we prepend A=0 instead of appending.

kent$ echo "some text A=10 some text some more text A more text some other text A=30 other text"|awk -F'A=' 'NF==1' 10 0 30 

This might work for you (GNU sed):

Look for the string A= followed by one or more numbers and if it occurs replace the whole line by the back reference. Otherwise replace the whole of the line by 0 .

+1 this is the only one that is 100% sed, is accurate enough and actually works (and also quite short). b.t.w. what does the ;t; between the two replacements ? (oh, btw, you even can scrap one of the 8 from the pattern) 🙂

@thom t checks to see if the last substitute command (if any) was a success and if so bails out. As there is no goto place name following the t command it ends the processing of the line. If the substitution was not a success (or no substitute has been done) it replaces the whole line with a 0 .

Источник

Как мне получить только цифры в grep?

Я хочу найти вхождение чисел в вышеуказанный файл. Я придумал:

Скорее хочу только 34 . Есть ли способ сделать это?

В будущем также ознакомьтесь со справочной страницей для grep (или любой другой программы). Страница man подробно описывает параметры, необходимые для многих распространенных применений программы. напр. man grep

Вы можете использовать grep -E для доступа к расширенному синтаксису регулярного выражения (То же, что egrep )

Я создал тестовый файл с содержанием ниже:

>cat testfile this is some text with some random lines again some text ok now going for numbers (:32) ok now going for numbers (:12) ok now going for numbers (:132) ok now going for numbers (:1324)

Теперь, чтобы извлечь только цифры из текста, который вы можете использовать

>grep -Eo '9' testfile 32 12 132 1324

Здесь «-o» используется только для вывода соответствующего сегмента строки, а не полного содержимого строки.

Квадратные скобки (например, ) указывают количество совпадений. требует, чтобы предыдущий символ или класс символов встречался хотя бы один раз, но не более четырех раз.

Приятно. Кроме того, чтобы соответствовать более 4 или произвольному количеству цифр, используйте grep -Eo '5<1,>' testfile

Вы можете использовать скобочное выражение RE, [:digit:] указанное в разделе 9.3.5 стандарта POSIX , в сочетании с -o флагом для печати только соответствующих «слов»

$ grep -o '[[:digit:]]*'  $'No number in this line\nbut 123 here' 123

grep -o будет печатать только соответствующую часть строки. В противном случае grep напечатает любые строки с шаблоном.

Я бы использовал curl для локального или удаленного доступа к вашему файлу, затем я бы собрал строки с числами, завернутыми в (:), затем обрезал эти фрагменты и записал в файл

принятый ответ игнорирует, что в предыдущих строках файла могут быть числа, он работает для данных примера, но что, если файл был удаленным?

curl file:///home/$USER/Public/input.txt | grep -o '(:.*)' | cut -d ":" -f 2 | cut -d ")" -f 1 > output.txt

В этом примере output.txt в вашей текущей папке будет перезаписано, мы получаем доступ input.txt из вашей общей папки.

curl https://yoursite.com/Public/input.txt | grep -o '(:.*)' | cut -d ":" -f 2 | cut -d ")" -f 1 > output.txt

Источник

Выделение числа из строки в выводе команды (Bash)

В переменной WAYSCAN хранится путь к утилите wayland-scanner. Необходимо получить версию этой утилиты и поместить её в другую переменную, однако вывод wayland-scanner --version выводит строку wayland-scanner 1.16.0 . Мне нужно из этой строки выделить только число. Знаю что это можно сделать с помощью регулярки, но как не пытался - не получается. Может кто подсказать решение, пожалуйста? Только чтобы работало как в Linux, так и BSD

Как в bsd не знаю, в linux можно так

wayland-scanner --version 2>&1 | egrep -o "9.*$"
wayland-scanner --version 2>&1 | awk ''

[20:16] u@notebook:~> echo 'wayland-scanner 1.16.0' | cut -d' ' -f2 1.16.0

Зачем тебе регулярки, если можно просто через col2 пропустить?

 ver=$(wayland-scanner --version) echo $ver wayland-scanner 1.16.0 ver=$ echo $ver 1.16.0 

legolegs ★★★★★ ( 25.01.19 21:20:33 MSK )
Последнее исправление: legolegs 25.01.19 21:21:34 MSK (всего исправлений: 1)

legolegs best.

Сделал так, однако получаю на выходе Illegal Number, а условие со сравнением версий отрабатывается некорректно (переменной CODEGEN всегда присвается значение «private-code»). Где ошибка?

#!/bin/sh WAYSCAN=/usr/bin/wayland-scanner WAYSCAN_VER=$($WAYSCAN --version 2>&1 | awk '') WAYLAND_PROTOS=/usr/share/wayland-protocols OUTPUT=gfx/common/wayland if [ ! -d $WAYLAND_PROTOS ]; then WAYSCAN=/usr/local/bin/wayland-scanner WAYLAND_PROTOS=/usr/local/share/wayland-protocols fi if [ ! -d $OUTPUT ]; then mkdir $OUTPUT fi #Since Wayland 1.15 option "code" is deprecated. Recommended to use "private-code" option instead. if [ "$WAYSCAN_VER -ge 1.15" ]; then CODEGEN=private-code else CODEGEN=code fi 

Понял. Дело в том, что пытаюсь сравнить дробные числа. Не подскажите как правильно всё сделать?

Про illegal number не понял, а по поводу сравнения версий, да, это так не работает.

CHECK="1.17" if [ "$(printf '%s\n' "$WAYSCAN_VER" "$CHECK" | sort -V | tail -1)" == "$WAYSCAN_VER" ]; then CODEGEN=private-code else CODEGEN=code fi + CHECK=1.17 ++ printf '%s\n' 1.16.0 1.17 ++ sort -V ++ tail -1 + '[' 1.17 == 1.16.0 ']' + CODEGEN=code
CHECK="1.15" if [ "$(printf '%s\n' "$WAYSCAN_VER" "$CHECK" | sort -V | tail -1)" == "$WAYSCAN_VER" ]; then CODEGEN=private-code else CODEGEN=code fi + CHECK=1.15 ++ printf '%s\n' 1.16.0 1.15 ++ sort -V ++ tail -1 + '[' 1.16.0 == 1.16.0 ']' + CODEGEN=private-code 

Мне нужно чтобы было >=1.15. Пытаюсь реализовать с помощью bc, но пока не получается

Так выше я привел код, который позволит сравнить версии.

А, хорошо, спасибо. Я просто не совсем понял как он работает. Но работает 🙂

-V, --version-sort natural sort of (version) numbers within text

Выводим сравниваемые версии в формате одна версия на одну строку. Потом с помощью sort -V распределяем их в образовавшейся колонке от меньшей версии к большей. tail'ом берем значение большей. Дальше сравниваем с полученной реальной версией wayland-scan. Если она равна самой большой версии, значит версия wayland-scan или той же версии, что и значение CHECK, т.е. 1.15, или выше. А если самая большая версия после tail не совпадает с версией wayland-scan, значит версия wayland-scan меньше.

Взгруснулось. Аж на комментарии хватило энтузиазма.

#!/usr/bin/env bash # compare version from $1 and $2 # parse the format "(programm_name[- ])?[[:num:]+](\.[[:num:]]+)*(-suffix)?" # ignore comparing a programm name and a suffix # returns: 0 - $1=$2, 1 - $1>$2, 2 - $1 vercmp() < local -a va1 va2 local ps='^(..*[- ])?(68*(.37*)*)(-..*)?$' IFS=. # test the format and remove if present programm_name[- ] and -suffix [[ $1 =~ $ps ]] || return 3 # set array=(ver_major ver_minor ver_patch. ) va1=($) # for $2 too [[ $2 =~ $ps ]] || return 4 va2=($) local -i i=0 c1 c2 while [[ "$$" ]]; do # Removing leading zeroes, set empty as 0 c1=$((10#$)) c2=$((10#$)) # compare a version item [[ c1 -lt c2 ]] && return 2 [[ c1 -ne c2 ]] && return 1 i=i+1 done return 0 > # testing tests() < vercmp "$1" "$2" echo "'$1' '$2' $? returned" > tests 1 0 tests 0 1 tests 1 1 tests 1.1 0 tests 0 1.1 tests 1 1.1 tests 1.1 1.1 tests 1.1 1 tests 1.2 tests a-1.3 b-1.3-suff tests a-1.3 a-1.25 tests "b0 " tests "c0 1" "c0 0.1" tests 1.2.8-suff 1.2.010-suff tests "p 1" "x 1.0" tests "p 1." "x 1.0" tests "p.1." "x.1.0" tests "p.1" "x.1.0" 

vodz ★★★★★ ( 26.01.19 12:43:42 MSK )
Последнее исправление: vodz 26.01.19 12:52:40 MSK (всего исправлений: 2)

Источник

Оцените статью
Adblock
detector