我在编写bash脚本时遇到了问题
cutfiles=`find $DIR -type f |
file -b $SAVEFILES |
cut -c1-40 |
sort -n |
uniq -c |
sort -nr |
head -10 |
while read -r n text; do
printf " %s...%$((40-${#text}))s: " "$text"
for ((i=0;i<$n;i++)); do
printf "%s" "#"
done
echo
done`
输出如下:
ASCII text... : #######
empty... : ####
Bourne-Again shell script, ASCII text...: ##
PDF document, version 1.4... : #
我想要做的是仅在文件类型长于40时才设置点。例如:
ASCII text : #######
empty : ####
Bourne-Again shell script, ASCII text...: ##
PDF document, version 1.4 : #
有办法吗?
答案 0 :(得分:1)
@PSkocik的awk
解决方案非常好
只是为了记录,你可以在没有awk
的情况下做更慢的事情。
如果你想在第37个pos之后更换一个字符串超过40个pos时的所有内容,你可以使用
sed 's/\(.\{37\}\).\{3\}.\+/\1.../' <<< "$text"
题外话:
你可以替换
for ((i=0;i<$n;i++)); do
printf "%s" "#"
done
echo
与
printf "%*.*s\n" $n $n '#' | tr ' ' '#'
编辑:
请注意,使用我的解决方案无法删除cut
,因为字符串的差异可能位于第40个位置之后,并且您希望输出中包含uniq行。当只有第38个pos不同时,您将得到不同的输出行,因此最好用cut
命令替换sed
命令。
答案 1 :(得分:0)
Yo可以使用awk(应该比bash更快,更便携):
filter()
{
awk -F: '{
if(length($1)>40) printf "%.37s...:%s\n",$1,$2; else printf "%-40s:%s\n", $1,$2;
}'
}
cat | filter <<EOF
ASCII text : #######
empty : ####
Bourne-Again shell script, ASCII text Lorem Ipsum: ##
PDF document, version 1.4 : #
EOF
输出:
ASCII text : #######
empty : ####
Bourne-Again shell script, ASCII text...: ##
PDF document, version 1.4 : #