我的程序遇到了问题。我有一个文件列表,我使用此代码对它们进行排序,以找出列表中最常用的10种文件类型。
find $DIR -type f | file -b $SAVEFILES | cut -c1-40 | sort -n | uniq -c | sort -nr | head -10
我的输出看起来像这样
168 HTML document, ASCII text
114 C source, ASCII text
102 ASCII text
33 ASCII text, with very long lines
30 HTML document, UTF-8 Unicode text, with
26 HTML document, ASCII text, with very lon
21 C source, UTF-8 Unicode text
20 LaTeX document, UTF-8 Unicode text, with
15 SVG Scalable Vector Graphics image
12 LaTeX document, ASCII text, with very lo
我想要做的是在文件类型之前访问值并替换它们#。我可以用for循环来表达,但首先我以某种方式访问它们。
预期的输出是这样的:
__HTML document, ASCII text : ################
__C source, ASCII text : ###########
__ASCII text : ##########
__ASCII text, with very long lines : ########
__HTML document, UTF-8 Unicode text, with : #######
__HTML document, ASCII text, with very lon: ####
__C source, UTF-8 Unicode text : ####
__LaTeX document, UTF-8 Unicode text, with: ###
__SVG Scalable Vector Graphics image : #
__LaTeX document, ASCII text, with very lo: #
编辑:#不代表我的例子中的exect数字。第一行应该有168#,第二行应该有114#,等等
答案 0 :(得分:1)
附加:
| while read -r n text; do printf "__%s%$((48-${#text}))s: " "$text"; for ((i=0;i<$n;i++)); do printf "%s" "#"; done; echo; done
根据您的需要更改48
。
输入时输出:
__HTML document, ASCII text : ######################################################################################################################################################################## __C source, ASCII text : ################################################################################################################## __ASCII text : ###################################################################################################### __ASCII text, with very long lines : ################################# __HTML document, UTF-8 Unicode text, with : ############################## __HTML document, ASCII text, with very lon : ########################## __C source, UTF-8 Unicode text : ##################### __LaTeX document, UTF-8 Unicode text, with : #################### __SVG Scalable Vector Graphics image : ############### __LaTeX document, ASCII text, with very lo : ############
答案 1 :(得分:1)
shell循环永远不是操作文本的正确方法,请参阅why-is-using-a-shell-loop-to-process-text-considered-bad-practice。
您可以使用此awk命令执行您要求的操作:
$ awk '{printf "%-40s: %s\n", substr($0,9), gensub(/ /,"#","g",sprintf("%*s",$1,""))}' file
HTML document, ASCII text : ########################################################################################################################################################################
C source, ASCII text : ##################################################################################################################
ASCII text : ######################################################################################################
ASCII text, with very long lines : #################################
HTML document, UTF-8 Unicode text, with : ##############################
HTML document, ASCII text, with very lon: ##########################
C source, UTF-8 Unicode text : #####################
LaTeX document, UTF-8 Unicode text, with: ####################
SVG Scalable Vector Graphics image : ###############
LaTeX document, ASCII text, with very lo: ############
但这样做的正确方法是摆脱cut
上的所有内容,并执行以下操作:
find "$DIR" -type f | file -b "$SAVEFILES" |
awk '
{ types[substr($0,1,40)]++ }
END {
PROCINFO["sorted_in"] = "@ind_num_desc"
for (type in types) {
printf "%-*s: %s\n", 40, type, gensub(/ /,"#","g",sprintf("%*s",cnt[type],""))
if (++cnt == 10) {
break
}
}
}
'
以上使用GNU awk for sorted_in和gensub()以及第二个是未经测试的,因为你只提供了最后一部分的样本输入,打印了&#34;#&#34; s
答案 2 :(得分:0)
perl方法,添加:
| perl -lpE 's/\s*(\d+)\s(.*)/sprintf "__%-40s: %s", $2, "#"x$1/e'
输出
__HTML document, ASCII text : ########################################################################################################################################################################
__C source, ASCII text : ##################################################################################################################
__ASCII text : ######################################################################################################
__ASCII text, with very long lines : #################################
__HTML document, UTF-8 Unicode text, with : ##############################
__HTML document, ASCII text, with very lon: ##########################
__C source, UTF-8 Unicode text : #####################
__LaTeX document, UTF-8 Unicode text, with: ####################
__SVG Scalable Vector Graphics image : ###############
__LaTeX document, ASCII text, with very lo: ############
按照@ Ed的方法,只使用perl
find "$DIR" -type f | file -b "$SAVEFILES" |\
perl -lnE '$s{substr$_,0,40}++;}{printf"__%-40s: %s\n",$_,"#"x$s{$_}for(splice@{[sort{$s{$b}<=>$s{$a}}keys%s]},0,9)'
可读:
perl -lnE '
$seen{ substr $_,0,40 }++;
END {
printf"__%-40s: %s\n", $_, "#" x $seen{$_}
for( splice @{[sort { $seen{$b} <=> $seen{$a} } keys %seen]},0,9 )
}'
Ps:请注意,文件工具只会测试$SAVEFILES
中的文件,因此find ... | file -b $SAVEFILES
毫无意义