繁体   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