问题
im trying to make this script to switch areas on wacom tablets, im using xsetwacom to configure the tablets,
this is how the script im trying to make looks (it works, but just with the first tablet)
#!/bin/bash
variable =`xsetwacom --list | awk '/stylus/ {print $7}'`
xsetwacom --set $variable area 123 123 123 123
this is how an output of xsetwacom --list looks
Wacom Intuos S Pad pad id: 21 type: PAD
Wacom Intuos S Pen stylus id: 22 type: STYLUS
Wacom Intuos S Pen eraser id: 23 type: ERASER
and with a different tablet connected
Wacom Bamboo 2FG 4x5 Pad pad id: 21 type: PAD
Wacom Bamboo 2FG 4x5 Ped stylus id: 22 type: STYLUS
Wacom Bamboo 2FG 4x5 Pen eraser id: 23 type: ERASER
Wacom Bamboo 2FG 4x5 Finger touch id: 24 type: TOUCH
So when i put another tablet, the value of the "$variable" that i get changes, because theres more words, how can i fix this, the value im looking for is the id number of stylus,Thanks!.
回答1:
Bash has built-in regex support, which can be used as follows:
id_re='id:[[:space:]]*([[:digit:]]+)' # assign regex to variable
while IFS= read -r line; do
[[ $line = *stylus* ]] || continue # skip lines without "stylus"
[[ $line =~ $id_re ]] || continue # match against regex, or skip the line otherwise
stylus_id=${BASH_REMATCH[1]} # take the match group from the regex
xsetwacom --set "$stylus_id" area 123 123 123 123 </dev/null
done < <(xsetwacom --list)
At https://ideone.com/amv9O1 you can see this running (with input coming from stdin rather than xsetwacom --list
, of course), and setting stylus_id
for both of your lines.
回答2:
Assuming you want to get ids, you can get them as third field from the end ($(NF - 2)
):
xsetwacom --list | awk '/stylus/ {print $(NF - 2)}'
Or you could change the field separator to 2+ spaces and just print the second field:
xsetwacom --list | awk --field-separator="[ ]{2,}" '/stylus/{print $2}'
It depends on how xsetwacom
would change the output for longer names.
Out of curiosity, here's "pure awk" version:
yes | awk '
{ if (!( "xsetwacom --list" | getline )) { exit; } }
$NF == "STYLUS" { system("xsetwacom --set " $(NF-2) " area 123 123 123 123") }
'
回答3:
Just count fields from the end instead of from the front:
awk '/stylus/{print $(NF-2)}'
e.g.:
$ cat file
Wacom Intuos S Pad pad id: 21 type: PAD
Wacom Intuos S Pen stylus id: 22 type: STYLUS
Wacom Intuos S Pen eraser id: 23 type: ERASER
Wacom Bamboo 2FG 4x5 Pad pad id: 21 type: PAD
Wacom Bamboo 2FG 4x5 Ped stylus id: 22 type: STYLUS
Wacom Bamboo 2FG 4x5 Pen eraser id: 23 type: ERASER
Wacom Bamboo 2FG 4x5 Finger touch id: 24 type: TOUCH
$ awk '/stylus/{print $(NF-2)}' file
22
22
回答4:
something like this?
$ ... | awk '/stylus/{for(i=1;i<NF;i++) if($i=="id:") {print $(i+1); exit}}'
find the token next to id:
来源:https://stackoverflow.com/questions/52087447/extract-a-column-in-bash-even-if-the-number-of-columns-before-it-can-change