我有这种类型的数据:
Folder : 1
Folder : 2
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
Folder : 3
VM: XXX
VM: XXX
Folder : 4
VM: XXX
VM: XXX
VM: XXX
VM: XXX
VM: XXX
Folder : 5
Folder : 6
etc ...
我可以在这个文件中检索VM的总数:
cat my_file | grep VM | wc -l
19
但是我想知道怎样才能得到这样的输出:
Folder : 1
Total VM : 0
Folder : 2
Total VM : 12
Folder : 3
Total VM : 2
Folder : 4
Total VM : 5
Folder : 5
Total VM : 0
Folder : 6
Total VM : 0
etc ...
我不知道如何检索虚拟机的数量在每个文件夹与bash…
有人告诉我怎么做吗?
使用自定义RS
的简化gnu-awk
:
awk -v RS='Folder *:[^n]+' 'hdr {print hdr; print "Total VM : " gsub(/[[:space:]]*VM:/, "&") ORS} {hdr=RT}' file
Folder : 1
Total VM : 0
Folder : 2
Total VM : 12
Folder : 3
Total VM : 2
Folder : 4
Total VM : 5
Folder : 5
Total VM : 0
Folder : 6
Total VM : 0
更易读的版本:
# we use RS with regex as /Folder :<rest of the line?/
# RT gives as value of matched text
awk -v RS='Folder *:[^n]+' '
hdr {
print hdr # print header line
# in gsub we match 0+ white space folowed by VM:
# dummy gsub replace match with itself but it returns no of matches
print "Total VM : " gsub(/[[:space:]]*VM:/, "&") ORS
}
{
hdr = RT # store value of RT in variable hdr
}' file
用你所展示的样本,你可以尝试以下,在GNUawk
中编写和测试。
awk '
/^Folder/{
if(prevFolder){
print prevFolder ORS "Total VM : " (vmVal?vmVal:0)
}
vmVal=""
prevFolder=$0
next
}
NF{
vmVal++
}
END{
if(prevFolder){
print prevFolder ORS "Total VM : " (vmVal?vmVal:0)
}
}
' Input_file
解决方案2:OR与函数方法尝试如下:
awk '
function checkVal(value){
if(value){
print value ORS "Total VM : " (vmVal?vmVal:0)
}
}
/^Folder/{
checkVal(prevFolder)
vmVal=""
prevFolder=$0
next
}
NF{
vmVal++
}
END{
checkVal(prevFolder)
}
' Input_file
解释:为以上代码添加详细的层次解释。
awk ' ##Starting awk program from here.
function checkVal(value){ ##Creating function named checkVal by passing value variable in it.
if(value){ ##Checking if value is NOT NULL then do following.
print value ORS "Total VM : " (vmVal?vmVal:0)
##Printing value ORS Total VM : and vmVal value or 0 if its NULL.
}
}
/^Folder/{ ##Checking condition if line starts from Folder then do following.
checkVal(prevFolder) ##Calling checkVal function with passing prevFolder value to it.
vmVal="" ##Nullifying vmVal here.
prevFolder=$0 ##Setting preFolder to current line here.
next ##next will skip all further statements from here.
}
NF{ ##Checking condition if NF is NOT NULL then do following.
vmVal++ ##Increment vmVal with 1 here.
}
END{ ##Starting END block of this program from here.
checkVal(prevFolder) ##Calling checkVal function with prevFolder value here.
}
' Input_file ##Mentioning Input_file name here.
使用GNU awk:
awk '/Folder/ { folder=$3;map[folder]=0;next } /VM:/ { map[folder]++ } END { PROCINFO["sorted_in"]="@ind_num_asc";for (i in map) { printf "Folder : %snTotal VM : %snn",i,map[i] } }' file
解释:
awk '/Folder/ { # Process lines starting with "Folder"
folder=$3; # Set variable folder to the third space delimited field
map[folder]=0; # Initialise an array map with the folder as the index and 0 as the value.
next
}
/VM:/ { # Process lines with VM
map[folder]++ # Increment the array for the folder
}
END {
PROCINFO["sorted_in"]="@ind_num_asc"; '# Set array ordering
for (i in map) {
printf "Folder : %snTotal VM : %snn",i,map[i] # Loop through the array and print the data in the format required.
}
}' file