Sed

顯示帶有描述的應用程序列表,省略“不合適”

  • October 1, 2022

我一直在編寫具有多種功能的腳本。

我正在嘗試添加一個函式,顯示“/usr/share/applications”文件夾中所有應用程序的 whatis 命令輸出,而不顯示“不合適”的行。

我目前的命令嘗試是:

whatis $(ls /usr/share/applications | cut -d "." -f 1) | grep -i -v "nothing appropriate"

我遇到的問題是 grep 命令似乎不起作用,因此仍然顯示包含片語“nothing proper”的行。

我還嘗試了許多替代方法,包括使用“replace”和“sed”命令將不需要的行轉換為空白區域,但這些也未能解決問題。

所有上述嘗試,我都嘗試過直接輸出命令,也嘗試過將輸出路由到文件中,並對文件的“cat”輸出執行過濾器。

有沒有人可以推薦任何替代品?

錯誤消息通常寫入stderr,而您只是通過管道stdout傳輸到grep. 要在類似 Bourne 的 shell 中同時通過管道傳輸 stdout 和 stderr,fish請執行以下操作:

whatis... 2>&1 | grep -v 'nothing appropriate'

請注意,這意味著 stdout 和 stderr 最終會合併到 stdout 上。

那裡的外殼看到了一個管道,因此它將其拆分為whatis... 2>&1grep -v 'nothing appropriate'用左側的標準輸出(文件描述符 1)作為管道的寫入端,而右側的標準輸入(fd 0)作為另一個管道的標準輸入(fd 0)。該管道的末端,每一方在單獨的程序中同時執行。

在每一側,處理重定向。2>&1說:將 fd 2 重定向到與 fd 1 上打開的相同的東西,這裡是管道。所以 fd 1 和 2 都進入管道。

類似 rc 的 shell 的等效語法是whatis... >[2=1] | grep...and with csh-like shell: whatis... |& grep...(也適用於 zsh)。

使用或ksh93,您也可以只發送到過濾管道:zsh``bash``stderr

whatis... 2> >(grep -v 'nothing appropriate' >&2)

但請注意,grep不會等待該命令,因此您可能最終會在命令返回後看到其他錯誤消息。這可以通過以下方式避免zsh

{whatis...} 2> >(grep -v 'nothing appropriate' >&2)

(或者在and中更痛苦ksh93``bash)。

yash中,您可以使用程序重定向(語法與程序替換相似,但不同之處在於它是重定向運算符,而不是擴展),同樣的問題是過濾命令未被等待:

whatis... 2>(grep -v 'nothing appropriate' >&2)

請注意,cut -d "." -f 1您最終會更改org.gnome.Settings.desktoporg而不是org.gnome.Settings. 因為您正在呼叫 split+glob,所以對於包含 of$IFS或 glob 字元的應用程序名稱也會遇到問題。

使用zsh,您可以:

whatis -- /usr/share/applications/*.desktop(:t:r) |& grep -v 'nothing appropriate'

where:t獲取t文件的 ail (dirname) 和:r根名稱(不帶副檔名),|&2>&1 |.

bash中,您可以執行以下操作:

(
 shopt -s failglob
 set /usr/share/applications/*.desktop
 set -- "${@##*/}"
 whatis -- "${@%.*}" 2>&1
) | grep -v 'nothing appropriate'

"${@##*/}"的等價物在哪裡:t"${@%.*}"的等價物:r

使用 GNU ls9.0 或更高版本,您還可以:

ls --zero /usr/share/applications/ |
 LC_ALL=C sed -zn 's/\.desktop$//p' |
 xargs -r0 whatis -- 2>&1 |
 grep -v 'nothing appropriate'

wherels --zero以可後處理的格式輸出列表,sed刪除.desktop副檔名並在有替換時輸出結果(因此排除沒有.desktop副檔名的文件),xargs將列表傳遞給whatis,並grep過濾掉nothing appropriate錯誤。

使用 GNU basename,您還可以:

(
 shopt -s failglob
 basename -zs .desktop /usr/share/applications/*.desktop
) |
 xargs -r0 whatis -- 2>&1 |
 grep -v 'nothing appropriate'

還要注意,桌面文件的名稱通常與它們執行的執行檔的名稱不匹配(如果有的話),因此很可能沒有相應的手冊頁。

除了將 rootname 傳遞給,您還可以提取這些文件whatis的一些欄位。.desktop例如:

(cd /usr/share/applications && 
 grep -HPom1 -e '^GenericName=\K.*' -- *.desktop
)

將提取GenericName這些文件中第一次出現的欄位的值。

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