我的配置文件中有这些行,
bindsym $mod+F2 exec gnome-terminal #Open terminal
bindsym $mod+p exec command /some/path" #Popup Dictionary
bindsym $mod+Mod1+l exec --no-startup-id /some/path/command #Dmenu for my books collection
bindsym Mod1+Control+b exec rxvt -e nnn #nnn file browser
我想awk
列出第二列以及#
.我正在awk
使用
awk '/bindsym/{print $2}' filename
我不确定如何获取#
.
首选输出是键,然后是注释文本:
$mod+F2 Open terminal
答案1
$ awk -v OFS='\t' '/^bindsym/ { key = $2; sub(".*#", ""); print key, $0 }' file
$mod+F2 Open terminal
$mod+p Popup Dictionary
$mod+Mod1+l Dmenu for my books collection
Mod1+Control+b nnn file browser
这用于awk
首先将每行上的第二个字段提取到bindsym
变量中key
。然后,它会删除#
该行之前的所有内容(包括该行)并打印key
该行的剩余内容,并以制表符作为分隔符。
替代输出格式:
$ awk '/^bindsym/ { key = $2; sub(".*#", ""); printf("%-20s\t%-20s\n", key, $0) }' file
$mod+F2 Open terminal
$mod+p Popup Dictionary
$mod+Mod1+l Dmenu for my books collection
Mod1+Control+b nnn file browser
逻辑是相同的,但输出为两个(左对齐)字段中的每一个分配 20 个字符,并在它们之间放置一个制表符(为了更好的测量)。
答案2
利用match()
GNU的功能来匹配从行到行尾的awk
部分#
awk '/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}' filep
该match()
函数使用第二个参数中的正则表达式中的匹配模式填充第三个参数中提供的数组。
在任何 POSIX 上awk
, 的第三个参数match()
是不是支持,但有几个特殊变量RSTART
,RLENGTH
它们标记开始和长度匹配组的。我们substr()
在当前行使用该函数来获取匹配的字符串
awk '/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}' file
要漂亮地打印输出,您可以使用printf()
其他答案中的函数。
答案3
这很容易做到sed
;因为您的数据并不是真正面向字段的,所以 awk 在这里并没有提供巨大的好处:
sed 's/^[^ ]* //;s/ .*#//' inputfile
翻译:
s/^[^ ]* //
删除第一个空格字符之前的所有内容。
s/ .*#//
删除从第一个(剩余)空格字符到#
该行最后一个字符的所有内容。
答案4
Step1: count=`awk '{print NR}'|sed -n '$p' filename`
Step2:for ((i=1;i<=$count;i++)); do awk -v i="$i" 'NR==i && $0 ~ /^bindsym/{print $2}' filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g"
output
for ((i=1;i<=$count;i++)); do awk -v i="$i" 'NR==i && $0 ~ /^bindsym/{print $2}' filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g"
$mod+F2 Open terminal
$mod+p Popup Dictionary
$mod+Mod1+l Dmenu for my books collection
Mod1+Control+b nnn file browser