[英]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.