如何使用awk打印用户使用的列表项
How to print list item use by user using awk
我有2个文件输入文件
input1 是用户名、工具和号码:
######
User: a
#####
aem 12
aqwt 24
#####
User: B
#####
aem 34
bwem 52
dd 12
#####
User: C
#####
aem 11
aqwt 2
dd 1
#####
input2 是工具列表:
aem
aqwt
bwem
dd
我想输出用户和工具,如果没有工具,它将分配 0:
Tool a B C
aem 12 34 11
aqwt 24 0 2
bwem 0 52 0
dd 0 12 1
我尝试用 awk 比较 file2 和 file1 来打印数字,但脚本也会打印注释行:
awk 'NR==FNR{a[];next} ( in a); {print } !( in a); {print "0"}' input2 input1
输出将是:
0
0
0
12
24
0
0
0
34
52
12
0
0
0
11
2
1
0
有人知道如何按列分隔它并使其跳过注释行吗?我是这个语言的新手,谢谢
请您尝试以下操作:
awk '
NR==FNR { # process "input2"
tool[FNR] = [=10=] # store the tool name in an array "tool"
ntool = FNR # count of tools
next # skip the following statements
}
/^User:/ { # "User" line in "input1"
gsub(/[^:]+: */, "") # extract the username
user[++nuser] = [=10=] # store the user name in an array "user"
next
}
!/^#/ { # non-comment line in "input1"
num[, nuser] = # store the number in an array "num"
}
END {
printf "Tool" # print the header line
for (j = 1; j <= nuser; j++) { # print the user names
printf("\t%s", user[j])
}
print ""
for (i = 1; i <= ntool; i++) { # print the body lines
printf("%s", tool[i]) # print the tool name
for (j = 1; j <= nuser; j++) {
printf("\t%d", num[tool[i], j]) # print the number indexed by tool name and nuser
}
print ""
}
}
' input2 input1
输出:
Tool a B C
aem 12 34 11
aqwt 24 0 2
bwem 0 52 0
dd 0 12 1
由于数组 num[]
的元素是使用 %d
格式打印的,未定义的值打印为 0
.
gsub(/[^:]+: */, "")
的解释:
- 如果确保
User
行的格式有空格
冒号后如User: a
,很容易提取用户名
通过仅使用变量 </code>.</li>
<li>我可能想多了,但我考虑了没有空格的情况
冒号后,例如 <code>User:a
.
- 语句
gsub(/[^:]+: */, "")
中的第一个参数/[^:]+: */
是匹配非冒号字符后跟冒号的正则表达式
和可能的(0 个或更多)空格。
gsub()
语句将上面匹配的子环替换为
第二个参数 ""
(空字符串)那么剩下的部分是
我们想要的名字,由[=24=]
. 持有
- 适当的函数可能是
sub()
,而不是 gsub()
,
尽管在这种情况下没有区别。
我有2个文件输入文件
input1 是用户名、工具和号码:
######
User: a
#####
aem 12
aqwt 24
#####
User: B
#####
aem 34
bwem 52
dd 12
#####
User: C
#####
aem 11
aqwt 2
dd 1
#####
input2 是工具列表:
aem
aqwt
bwem
dd
我想输出用户和工具,如果没有工具,它将分配 0:
Tool a B C
aem 12 34 11
aqwt 24 0 2
bwem 0 52 0
dd 0 12 1
我尝试用 awk 比较 file2 和 file1 来打印数字,但脚本也会打印注释行:
awk 'NR==FNR{a[];next} ( in a); {print } !( in a); {print "0"}' input2 input1
输出将是:
0
0
0
12
24
0
0
0
34
52
12
0
0
0
11
2
1
0
有人知道如何按列分隔它并使其跳过注释行吗?我是这个语言的新手,谢谢
请您尝试以下操作:
awk '
NR==FNR { # process "input2"
tool[FNR] = [=10=] # store the tool name in an array "tool"
ntool = FNR # count of tools
next # skip the following statements
}
/^User:/ { # "User" line in "input1"
gsub(/[^:]+: */, "") # extract the username
user[++nuser] = [=10=] # store the user name in an array "user"
next
}
!/^#/ { # non-comment line in "input1"
num[, nuser] = # store the number in an array "num"
}
END {
printf "Tool" # print the header line
for (j = 1; j <= nuser; j++) { # print the user names
printf("\t%s", user[j])
}
print ""
for (i = 1; i <= ntool; i++) { # print the body lines
printf("%s", tool[i]) # print the tool name
for (j = 1; j <= nuser; j++) {
printf("\t%d", num[tool[i], j]) # print the number indexed by tool name and nuser
}
print ""
}
}
' input2 input1
输出:
Tool a B C
aem 12 34 11
aqwt 24 0 2
bwem 0 52 0
dd 0 12 1
由于数组 num[]
的元素是使用 %d
格式打印的,未定义的值打印为 0
.
gsub(/[^:]+: */, "")
的解释:
- 如果确保
User
行的格式有空格 冒号后如User: a
,很容易提取用户名 通过仅使用变量</code>.</li> <li>我可能想多了,但我考虑了没有空格的情况 冒号后,例如 <code>User:a
. - 语句
gsub(/[^:]+: */, "")
中的第一个参数/[^:]+: */
是匹配非冒号字符后跟冒号的正则表达式 和可能的(0 个或更多)空格。 gsub()
语句将上面匹配的子环替换为 第二个参数""
(空字符串)那么剩下的部分是 我们想要的名字,由[=24=]
. 持有
- 适当的函数可能是
sub()
,而不是gsub()
, 尽管在这种情况下没有区别。