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