我正在编写一个从基本文件生成别名/缩写的脚本。基本文件结构是这样的:
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"
但是当该行在第三个参数之后包含很多部分时,此代码将不起作用:
svu playerctl -p spotify volume +0.05
如何进行这种格式的打印? $ 1 $ 2($ 3 .. $ N)
答案 0 :(得分:2)
您可以删除前两个字段,并从其余部分中修剪空间,例如。
{
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。
答案 1 :(得分:2)
使用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"
上面的\s
和\S
使用GNU awk-其他awks则使用[[:space:]]
和[^[:space:]]
。
但是,由于我们使用的是GNU awk,所以我们可以使用第三个arg来match()来更简洁,更高效地完成工作:
$ 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"
答案 2 :(得分:1)
用另外两个字段替换掉。
$ 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
从前两个字段的残余中删除输出字段分隔符。
答案 3 :(得分:1)
这是一个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"
答案 4 :(得分:0)
这是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
,{ {1}}。请注意,上述sed命令中使用\3
标志来启用扩展的正则表达式。如果该标志在目标计算机上不可用,则可以使用以下命令:
-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"
,(
,)
在稍后被转义。