Home > other >  Awk equivalent in PowerShell to apply to console outputted table
Awk equivalent in PowerShell to apply to console outputted table

Time:04-29

I've looked at many solutions online, but none relate to my specific situation. I have following PowerShell command output:

    PS C:\Users\Administrator> Query User | Select-String "rdp"

>administrator         rdp-tcp#7           2  Active          .  4/28/2022 10:22 AM

If I were using bash, it would be a simple case of using awk to select the 2nd column (which is the one I require).

Can anyone help me with how I would achieve the same result in PowerShell?

CodePudding user response:

You may just use $ENV:SESSIONNAME to get that string.

If you want to play with a bit of code to "emulate" awk, you can use

((Query User) -match 'rdp' -split '\s ')[1]

Note:

  • (Query User) - The string returned by Query User...
  • ... -match 'rdp' - is first matched with rdp, and once the match is obtained,
  • ... -split '\s ' - it is split with one or more whitespaces.
  • (...)[1] - Then, the second item is returned using indexing, [1] (since array indices are zero-based).

CodePudding user response:

Wiktor Stribiżew's answer provides an effective solution for a single matching line (which may be all that is needed in this case).

To generalize and elaborate on the AWK angle:

  • If fields need to be extracted from multiple lines, you need multiple calls to the -split operator.

    • It is the unary form, of -split, as used below, that behaves AWK-like with respect to field splitting, in that any nonempty run of whitespace separates fields, with leading and trailing whitespace getting ignored.
  • For processing multiple lines one by one, you can use the switch statement, which is AWK-inspired too.

The equivalent of this AWK command, which extracts the 2nd field from each line containing the string "rdp":

query user | awk '/rdp/ { print $2 }'

is this switch statement:

switch -Regex (query user) { 'rdp' { (-split $_)[1] } }

Note:

  • 0-based array indexing applies in PowerShell, because the -split operator returns an array of tokens; by contrast, AWK's field numbering start with $1 ($0 representing the whole line). That is, field $2 in AWK corresponds to array index 1 in PowerShell.

  • Add -CaseSensitive if needed; PowerShell is case-INsensitive by default.


Optional reading: grep vs. Select-String:

Another Unix-utility solution option is to use grep, as follows:

query user | grep -Eo '\brdp[^ ] '

PowerShell's grep analog is Select-String.

As of PowerShell 7.2.2, there is a pending, green-lighted future improvement to Select-String that would allow returning just the matched part of matching lines, analogous to grep's -o; community members are welcome to implement it - see GitHub issue #7712.

# FUTURE improvement.
query user | Select-String -OnlyMatching '\brdp[^ ] '

For now, a more verbose solution is required:

query user | Select-String '\brdp[^ ] ' | ForEach-Object { $_.Matches.Value }
  • Related