簡體   English   中英

如何在AWK中一起打印$ 1,$ 2和所有剩余參數

[英]How to print $1, $2 and then all remaining parameters together in AWK

我正在創建一個從基本文件生成別名/縮寫的腳本。 基本文件結構是這樣的:

sctl   sudo         systemctl
pac    sudo         pacman

這適用於下面的代碼,它讀取基本文件,刪除注釋並解釋縮寫文件中的縮寫行:

    sed "s/\s*#.*$//;/^\s*$/d" $command_file | 
    awk -v c=$cmd -v o="$comp" '{ print c" "$1""o"\""$2" "$3"\"" }' >> $file

最終結果將是這樣的:

abbr sctl "sudo systemctl"
abbr pac "sudo pacman"

但是當第3個參數后行有很多部分時,此代碼不起作用:

svu    playerctl    -p spotify volume +0.05

我怎樣才能以這種格式打印? $ 1 $ 2($ 3 .. $ N)

您可以擦除前兩個字段並從剩余部分修剪空間,例如。

{ 
  printf "%s %s ", $1, $2
  $1=$2=""; sub(/^\s*/, "", $0);
  printf "\"%s\"\n", $0
}

輸出像,

svu playerctl "-p spotify volume +0.05"

注意: \\s正則表達式需要Ed Morton指出的gnu awk。

當你使用awk時,你永遠不需要sed。 給定此輸入文件:

$ cat file
sctl   sudo         systemctl   # here is a comment
        # and here is another
pac    sudo         pacman

svu    playerctl    -p spotify volume +0.05

這是你的sed + awk輸出:

$ sed "s/\s*#.*$//;/^\s*$/d" file |  awk -v c="abbr" -v o=" " '{ print c" "$1""o"\""$2" "$3"\"" }'
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p"

你可以從awk單獨獲得:

$ awk -v c="abbr" -v o=" " '{sub(/\s*#.*/,"")} NF{print c" "$1""o"\""$2" "$3"\""}' file
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p"

然后您可以調整以執行您想要的操作:

$ awk -v c="abbr" -v o=" " '{sub(/\s*#.*/,"")} NF{x=$1; sub(/^\S+\s+/,""); $1=$1; print c, x o "\"" $0 "\""}' file
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p spotify volume +0.05"

或者(我無法從你的問題中告訴你在雙引號內/外的內容):

$ awk -v c="abbr" -v o=" " '{sub(/\s*#.*/,"")} NF{x=$1" "$2; sub(/^(\S+\s+){2}/,""); $1=$1; print c, x o "\"" $0 "\""}' file
abbr sctl sudo "systemctl"
abbr pac sudo "pacman"
abbr svu playerctl "-p spotify volume +0.05"

以上使用GNU awk for \\s\\S - 與其他awks使用[[:space:]][^[:space:]]代替。

既然我們正在使用GNU awk,那么我們可以通過第3個arg來更簡潔有效地完成工作來匹配():

$ awk -v c="abbr" -v o=" " '{sub(/\s*#.*/,""); $1=$1} match($0,/(\S+) (.*)/,a){print c, a[1] o "\"" a[2] "\""}' file
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p spotify volume +0.05"

$ awk -v c="abbr" -v o=" " '{sub(/\s*#.*/,""); $1=$1} match($0,/(\S+ \S+) (.*)/,a){print c, a[1] o "\"" a[2] "\""}' file
abbr sctl sudo "systemctl"
abbr pac sudo "pacman"
abbr svu playerctl "-p spotify volume +0.05"

替換兩個額外的字段不存在。

$ echo "svu playerctl -p spotify volume +0.05" | gawk '
  { print $1; $1 = ""
    print $2; $2 = ""
    print substr($0,3) } '
svu
playerctl
-p spotify volume +0.05

substr從前兩個字段的殘余中刪除輸出字段分隔符。

這是一個awk(標准的Linux特定於gawk)腳本,它在一次掃描中完成所有工作:

awk -v c="abbr" -v o=" " '/(^\s*$)|(^\s*#.*$)/ {next}  # discard empty lines and comments
{
    arg3=$0;                          # save current line to arg3 variable
    sub($1" "$2,"",arg3);             # remove $1  and $2 from arg3
    print(c" "$1""o"\""$2" "arg3"\"") # print formated output
}' input.txt

input.txt中

ctl   sudo         systemctl
# comment line
pac    sudo         pacman
   # comment line
demo1  sudo         arg1 arg2 arg3

demo2  sudo         arg4 -arg5 -arg6 456
                         # comment line

輸出:

abbr ctl "sudo          systemctl"
abbr pac "sudo          pacman"
abbr demo1 "sudo          arg1 arg2 arg3"
abbr demo2 "sudo          arg4 -arg5 -arg6 456"

這是GNU sed版本:

sed -r 's/(^[^ ]+)\s+([^ ]+)\s+(.*)/abbr \1 "\2 \3"/g' base_file
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p spotify volume +0.05"

說明:此處使用反向引用,每列被捕獲到相應的組中,稍后用作\\1\\2\\3 請注意,在上面的sed命令中使用-r標志來啟用擴展的正則表達式。 如果目標計算機中沒有此標志,則可以使用以下命令:

sed  's/\(^[^ ]\+\)\s\+\([^ ]\+\)\s\+\(.*\)/abbr \1 "\2 \3"/g' base_file
abbr sctl "sudo systemctl"
abbr pac "sudo pacman"
abbr svu "playerctl -p spotify volume +0.05"

只有()+中的兩個命令的差異在后面被轉義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM