Shell

帶有換行符、逗號和引號的 zsh 別名

  • February 16, 2018

在我的 zshrc 中,我有一個這樣的別名:

alias sl='screen -list'

它符合我的需要(查看我正在執行的螢幕),但輸出相當難看:

[pts/7]~% sl
There are screens on:
       32765.quotes-api        (04/26/2015 11:09:18 AM)        (Detached)
       5055.gitsync-test       (04/07/2015 09:24:04 PM)        (Detached)
       15074.gitsync-interceptor       (03/31/2015 10:39:45 AM)        (Detached)
       4662.eloquent-api    (03/29/2015 11:37:26 AM)        (Detached)
       16177.Dropbox   (03/17/2015 03:53:44 PM)        (Detached)
       18803.gitsync-todo-api-py       (03/06/2015 08:21:24 AM)        (Detached)
       796.website (01/31/2015 01:56:02 PM)        (Detached)
       7874.gitsync-optionals  (01/29/2015 02:27:24 PM)        (Detached)
       28474.linkbag   (12/16/2014 09:56:39 AM)        (Detached)
       10839.datapump  (10/13/2014 02:16:26 PM)        (Detached)
       5118.resr-api-python        (09/13/2014 12:28:33 PM)        (Detached)
       7619.dataglobbing    (09/03/2014 08:34:13 PM)        (Detached)
       10583.rest-api-dataglobbing  (09/03/2014 01:06:21 AM)        (Detached)
       11705.save-functions    (08/12/2014 01:00:58 PM)        (Detached)
14 Sockets in /var/run/screen/S-tuvokki.

所以我開始格式化它並得到以下工作:

screen -list|grep -v There|grep -v Sockets|awk 'BEGIN { format = " %-35s %-10s %s\n"
        printf format, "Name", "Active", "Status"
        printf format, "----", "------", "------" }
      { printf format, $1, $2, $5 }'

但是我如何把它放在一個別名中,就像我之前的簡單命令一樣?

僅僅把它放在一條線上是行不通的。我試圖轉義引號,使用雙引號而不是單引號給出解析錯誤。我也嘗試將它包裝在一個函式中,但似乎 awk 命令依賴於換行符並且不喜歡所有指令都在一行上。

您可以通過三種方式解決此問題。

一:只使用一個函式。別名用於簡單的文本宏,而您的第二個範例則不是。

sl() {
screen -list|grep -v There|grep -v Sockets|awk 'BEGIN { format = " %-35s %-10s %s\n"
        printf format, "Name", "Active", "Status"
        printf format, "----", "------", "------" }
      { printf format, $1, $2, $5 }'
}

二:使用quote-linewidget正確轉義整個命令

# type the entire command out like you would interactively.
% screen -list|grep -v There|grep -v Sockets|awk 'BEGIN { format = " %-35s %-10s %s\n"
    printf format, "Name", "Active", "Status"
    printf format, "----", "------", "------" }
  { printf format, $1, $2, $5 }'
# use quote-line which transform the line into:
% 'screen -list|grep -v There|grep -v Sockets|awk '\''BEGIN { format = " %-35s %-10s %s\n"
    printf format, "Name", "Active", "Status"
    printf format, "----", "------", "------" }
  { printf format, $1, $2, $5 }'\'''
# prepend alias sl= to the newly escaped line:
% alias sl='screen -list|grep -v There|grep -v Sockets|awk '\''BEGIN { format = " %-35s %-10s %s\n"
    printf format, "Name", "Active", "Status"
    printf format, "----", "------", "------" }
  { printf format, $1, $2, $5 }'\'''

第三:只使用一個函式。別名用於簡單的文本宏。

sl() {
screen -list|grep -v There|grep -v Sockets|awk 'BEGIN { format = " %-35s %-10s %s\n"
        printf format, "Name", "Active", "Status"
        printf format, "----", "------", "------" }
      { printf format, $1, $2, $5 }'
}

awk 範例也不依賴換行符,但您需要;在同一行上分隔多個語句。

screen -list|grep -v There|grep -v Sockets|awk 'BEGIN { format = " %-35s %-10s %s
"; printf format, "Name", "Active", "Status"; printf format, "----", "------", "------" } { printf format, $1, $2, $5 }'

將工作。

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