Bash

僅從 wmctrl -l 獲取應用程序名稱

  • February 4, 2017

我試圖從這段程式碼中獲取應用程序名稱:

wmctrl -l

但我不知道該怎麼做!

如果你能解釋一下我是怎麼做到的,那就太好了。

編輯:

的輸出wmctrl -l是:

0x01000007 -1 parrot Top Expanded Edge Panel
0x01000017 -1 parrot Bottom Expanded Edge Panel
0x01200006 -1 parrot x-caja-desktop
0x03600006  0 parrot Terminal
0x03000130  0 parrot scripting - Getting a string after a word in BASH - Unix & Linux Stack Exchange - Google Chrome

所以我需要之後的一切parrot

有幾種方法可以做到這一點。根據您喜歡的工具類型,您可以選擇其中一種

AWK

最合適的方式。將單詞 1,2,3 設置為空字元串並列印

$ wmctrl -l | awk '{$1=$2=$3="";print}'  

或者,要擺脫領先空間,您可以這樣做:

$ wmctrl -l | awk '{for(i=4;i<=NF;i++) printf "%s ",$i;print ""}'

有點尷尬的方法,我們在特定欄位之後列印所有內容,直到欄位 9999。為什麼 9999 ?-fflag 顯然需要知道範圍,因此對於每行有任意數量的單詞的輸入,我們顯然無法知道範圍,但我們可以使用足夠大的東西,因此是 9999。

$ wmctrl -l | cut -d " " -f 5-9999

Perl

我們可以利用-a自動拆分模式,將從標準輸入讀取的每一行的單詞拆分為數組。這可能會得到改進和縮短。

$ wmctrl  -l | perl -lane 'my $numels=scalar @F;print @F[3..$numels]'

Python

略長但有效。Python 沒有像 perl 這樣的自動拆分模式,但我們可以在讀取的每個字元串上​​手動執行此操作。

$ wmctrl -l | python -c "import sys; print '\n'.join([' '.join(line.split()[3:]) for line in sys.stdin])"

或者,我們可以使用一個簡短的腳本來模擬cut,而不是單行。這對於多行文本/輸入會更好,並且更具可讀性

#!/usr/bin/env python
import sys

start=int(sys.argv[1])
for line in sys.stdin:
   print " ".join(line.strip().split()[start:])

並這樣稱呼它:

$ wmctrl -l | ./print_words.py 3

SED

這種方式利用了正則表達式。我們從行首^到單詞邊界parrot\b空格匹配字元串,並刪除它們(有效設置為空字元串)

$ wmctrl -l | sed 's/^.*\bparrot\ //'

或者,為了避免貪婪匹配,我們可以使用以下內容:

$ wmctrl -l | sed 's/^[^ ]* *[^ ]* *[^ ]* //'

模式並不太複雜。我們從行首開始匹配,並匹配任意數量的*非空格([^ ]部分)字元(部分),由任意數量的空格分隔三遍。所以 ^[^ ]*匹配第一個單詞,*匹配任意數量的空格,第二個[^ ]*匹配第二個單詞,第二個*匹配第二個空格,最後[^ ]*匹配第三個單詞加空格。

BASH + xargs

我們可以利用 bash 迭代命令行參數的能力,並將每一行( -L 1 )作為命令行參數的集合傳遞給bash -c ' '. 剩下的很簡單——我們去掉前 3 個參數,然後列印剩下的

wmctrl -l | xargs -L 1 bash -c 'for i in 1 2 3;do shift ; done ; printf "%s " "$@";printf "\n"' sh

或者,正如 Stephane Chazelas 在評論中所建議的那樣:只要至少有 3 個位置參數從中傳遞wmctrl -l(在這種情況下應該始終正確),解決方案可以縮短為:

wmctrl -l | xargs -L 1 bash -c 'shift 3;printf "%s " "$@";printf "\n"' sh

引用自:https://unix.stackexchange.com/questions/342404