0

I'm trying to do some simple parsing of the output of the xinput command in a shell script. What I am trying to do works perfectly on the commandline, but doesn't work in the script.

Here is my commandline:

xinput list | awk '/Name of my Device   id[0-9]*    \[slave pointer/'

The output of the previous command:

⎜   ↳ Name of my Device      id=12   [slave  pointer  (2)]

When at the prompt, I input the tabs by hitting CTRL-V,TAB. When in the script, I input a line which reads:

xinput list | awk '/Name of my Device   id[0-9]*/'

Which returns three lines of data. As soon as I add another tab, like so:

xinput list | awk '/Name of my Device   id[0-9]*    /'

I no longer get any output. I tried with both CTRL-V,TAB and just with TAB. I've also tried manually typing the whole script line from scratch in case there was a non-printable in there somewhere. Why is awk able to deal with the first tab, but not the second? BTW, I've tried this with dash, bash, and zsh. The behavior is identical.

Thank you very much.

P.S. I forgot to mention my editor is vim.

P.P.S

xinput list | awk '/Name of my Device   id[0-9]*    \[slave pointer/' |
    sed 'y/ \t/_$/'

outputs:

⎜___↳_Name_of_my_Device$id=12$[slave__pointer__(2)]
Tripp Kinetics
  • 5,178
  • 2
  • 23
  • 37
  • What is the output of `xinput list` – Inian May 28 '18 at 19:17
  • Can you save the output of `xinput list` to a file and then cat the file with `cat -t` so we can see the tabs (and add it into your question)? – jas May 28 '18 at 19:25
  • Did one better. Marked the spaces and tabs. If you want me to mark the other non-printables, I can. – Tripp Kinetics May 28 '18 at 19:36
  • 1
    Okay, well that had me stumped for a bit, but in the end it's just a typo. You're missing the `=` in `id[0-9]*`. Try with `xinput list | awk '/Name of my Device id=[0-9]* /'` and you should be fine. – jas May 28 '18 at 20:17
  • 1
    Also, you might find it easier to use `\t` instead of literal tabs: `awk '/Name of my Device\tid=[0-9]*\t/'` should work just as well. – jas May 28 '18 at 20:18
  • @jas You're a lifesaver. However, it did not work when I used `\t` for some reason. Does start working with the `=` sign. Don't know why it *doesn't* work without the tab ***and*** without the `=` sign, though. – Tripp Kinetics May 28 '18 at 21:45
  • 1
    Without the tab and without the `=` it works because `id[0-9]*` matches `id` followed by _zero_ or more digits, so the presence of the `=` doesn't kill the match. Once you add the ``, though, the `=` gets in the way! – jas May 28 '18 at 21:52
  • 1
    This will illustrate what's being matched in that case: `echo ' ↳ Name of my Device id=12 [slave pointer (2)]' | awk '{sub(/Name of my Device id[0-9]*/, "XXX"); print}'` – jas May 28 '18 at 21:53
  • If you put in an answer, I'd be happy to accept. – Tripp Kinetics May 28 '18 at 22:03

1 Answers1

1

Turns out the extra tab was a bit of a red herring. Really it was a missing = in the pattern that was causing the problem:

xinput list | awk '/Name of my Device id=[0-9]* /'

is the corrected version.

Without the <tab> and without the = it works because id[0-9]* matches id followed by zero or more digits, so the presence of the = doesn't kill the match. Once you add the <tab>, though, the = gets in the way.

running

echo ' ↳ Name of my Device  id=12   [slave pointer (2)]' | awk '{sub(/Name of my Device id[0-9]*/, "XXX"); print}'

will illustrate what was getting matched when both the = and <tab> were missing.

jas
  • 10,715
  • 2
  • 30
  • 41