Я искал решение в Bash, которое может извлечь конкретную информацию после указанной строки.
Например (из acpi
):
Battery 0: Discharging, 37%, 01:33:20 remaining
Как извлечь процент после выписки? В этом случае это будет 37%
...
Я ищу простое решение, которое не требует набора командных аргументов.
Я не уверен, что вы имеете в виду, говоря «решение в bash», но awk
может сделать эту работу:
awk -F", " '{print$2}'
-F", "
- выберите запятую, а затем пробел в качестве разделителя F
, это разбивает строку примера на три столбца, где второй - 37%
'{print$2}'
- выведите второй столбец Или как насчет sed
?
sed -E 's/.* ([0-9]+%).*/\1/'
Вот некоторые из них:
$ acpi | grep -oP '\d+%'
99%
$ acpi | awk -F',' '{print $2}'
99%
$ acpi | perl -pe 's/.*?(\d+%).*/$1/'
99%
Я искал решение в bash, которое может извлечь конкретную информацию после указанной строки.
После заданной строки? Ни один из двух ранее опубликованных ответов не сделал именно этого (поскольку захват текста после строки - не лучший способ получить информацию, которую, как вы сказали, вы хотели получить в своем примере).
Вот несколько способов получить текст после строки. Я использовал ваш пример, хотя оба ответа Десерта и Тердона демонстрируют более подходящие подходы к этому конкретному случаю.
Используйте \K
из Perl, например, в grep
с -P
(разрешить регулярное выражение Perl) и -o
(только совпадение):
grep -Po 'string\Kdesired'
Где string
- выражение соответствует тому, что находится перед тем, что вы хотите, и desired
- это выражение, совпадающее с тем, что вы хотите вывести. Это полезно, когда требуемый шаблон встречается в другом месте файла / строки (например, это число, а файл / строка содержит другие числа). В вашем примере это может быть что-то вроде:
$ acpi | grep -Po 'ing, \K[^,]+'
79%
[^,]+
означает некоторые символы, которые не являются запятой, поэтому это может захватывать текст до запятой. Мы также могли бы использовать ...
, чтобы получить любые три символа, но, как указано в комментарии PerlDuck , вполне возможно, что шаблон, который вы здесь хотите, будет больше или меньше 3 символов.
В sed
вы можете использовать группы захвата с (
и )
:
sed -r 's/.*string(desired).*/\1/'
, где \1
- это то, что было сохранено с (
)
. Для вашего примера:
$ acpi | sed -r 's/.*ing, ([^,]+).*/\1/'
89%
Вот способ сделать это только с помощью Bash на вашем примере
$ output=$(acpi); string="${output#*ing, *}"; desired="${string%,*}"; echo "$desired"
96%
${var#string*}
обрезает var
до string
(включительно) и ${var%string*}
обрезает var
после string
(включительно).
Решение для bash, как и было запрошено, без неуклюжих акизмов или оскорблений:
my_battery=( $(acpi) ); echo ${my_battery[3]}
Использует подстановку команды, создает массив вывода команды и отображает 4-й элемент массива.
Это работает с выходом acpi, который, по-видимому, всегда имеет процент батареи в качестве 4-го параметра. Если вы хотите найти элемент массива после «Разряда», вы не получите результат, если acpi сообщит вам «Батарея 0: Полное, 100%».
Вы также можете использовать извлечение подстроки с расширением параметра
input=$(acpi)
expr "${input#*,[[:space:]]}" : '\([^,]*\)'