[\ x80- \ xFF]
включает только кодовые точки от 128 до 255. В зависимости от локали, в частности от кодировки символов , это может быть или не быть набор символов, отличных от ASCII. Это только в случае 8-битных кодировок. (8-битные кодировки на основе ASCII, если быть точным, но вы вряд ли встретите что-либо еще.) В регионах, где символ не является однобайтным, включая UTF-8, который является стандартом де-факто, [\ x80- \ xFF]
- это лишь небольшое подмножество символов, отличных от ASCII.
Самый простой способ поиска символов, отличных от ASCII, - это установить языковой стандарт C. В языковом стандарте C символ - это байт. Использование локали unibyte также значительно ускоряет некоторые версии GNU grep.
LC_ALL=C grep --color='auto' -P -n "[\x80-\xFF]" file.tex
Данные, которые вы получаете обратно из upsc
, имеет вид ключевое слово: value
, по одному на строку. Вы можете передать это через sed
, чтобы получить форму [keyword]="value"
, а затем использовать это для инициализации ассоциативного массива:
declare -A status="($(upsc myups | sed 's/\(.*\): \(.*\)/ [\1]="\2"/'))"
Теперь вы можете получить значение любого ключевого слова, например echo "${status[device.model]}"
.
Вы можете зациклиться на всех ключах и значениях и делать то, что хотите:
for key in "${!status[@]}"
do echo "$key: ${status[$key]}"
done
Обратите внимание, что если вы цитируете свои значения,
status="$(upsc myups)"
echo "${status[@]}"
вы все равно получите одно значение, но каждое значение будет в новой строке, как в желаемом выводе.
Вы можете использовать встроенный readarray
bash:
readarray status < <(upsc myups)
Вы можете подумать:
upsc myups | grep -oP 'battery(\.\w+)+: \S+'
Ваша основная потребность - указать ваши переменные в кавычках:
status=$(upsc myups)
echo "$status"
Самое простое решение - присвоить $ status
массив (т.е. заключенный в круглые скобки), а не строку.
Также установите IFS на новую строку ( \ n
), чтобы каждая строка (а не каждое слово) помещалась в отдельный элемент массива:
$ IFS=$'\n' status=( $(upsc myups 2>/dev/null | grep '^battery\.') )
$ printf "%s\n" "${status[@]}"
battery.capacity: 9.00
battery.charge: 90
battery.charge.low: 20
battery.charge.restart: 0
battery.energysave: no
battery.protection: yes
$ declare -p status # reformatted slightly for readability.
declare -a status='([0]="battery.capacity: 9.00" [1]="battery.charge: 90"
[2]="battery.charge.low: 20" [3]="battery.charge.restart: 0"
[4]="battery.energysave: no" [5]="battery.protection: yes")'
PS: Если вы собираетесь сделать значительно больше обработки с этими значениями upsc
, я настоятельно рекомендую использовать perl
или awk
или python
вместо bash
- все они гораздо лучше подходят для написания сложных инструментов обработки текста, чем только bash
.