僅從 wmctrl -l 獲取應用程序名稱
我試圖從這段程式碼中獲取應用程序名稱:
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 ?
-f
flag 顯然需要知道範圍,因此對於每行有任意數量的單詞的輸入,我們顯然無法知道範圍,但我們可以使用足夠大的東西,因此是 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