将数字替换为一个字符的相同值(数字)

将数字替换为一个字符的相同值(数字)

我必须使用 查找所有文件类型file -b $(find . -type f),将它们分类为唯一的类别,并打印出前 4 个类别,其中数字替换为相同数量的“#”。输出应如下所示:

 8 empty                      : ########
 6 ASCII text                 : ######
 3 Vim swap file, version 7.4 : ###
 1 UTF-8 Unicode text         : #

我不知道如何将每个类别中的文件数量打印为“#”标记。

我想要将每行上的数字作为值,并在末尾放置相同数量的“#”标记。

答案1

为了回答您的主要问题“如何用 N 个字符的序列来表示数字 N”,这里有一个 shell 命令可以做到这一点:

n=17          # Number to translate to a sequence
printf "%${n}s" '' | tr ' ' '#'

(替代语法:printf '%*s' "$n" '' | tr ' ' '#';还有其他替代方案,您明白了)

它的作用是生成一个由n空格(printf部分)组成的空行,然后将每个空格转换为所需的字符(tr部分)。

假设您有一个命令count_files可以输出问题中包含的列表,则可以像这样使用该命令:

count_files \
| while read n type; do 
    printf '%4d %-30s %s\n' "$n" "$type" "$(printf "%${n}s" '' | tr ' ' '#')"
done

...你会得到这个:

   8 empty                          ########
   6 ASCII text                     ######
   3 Vim swap file, version 7.4     ###
   1 UTF-8 Unicode text             #

答案2

在 Perl 中,可以使用运算符将​​一个字符重复多次x

$ perl -e 'print "#" x 10, "\n"'
##########

让我们使用它。

而不是解析输出find

find . -type f -exec file -b {} + | sort | uniq -c | sort -rn |
perl -ne 'chomp; s/\s+(\d+)\s+// && printf("%-3d %-50s: %s\n", $1, $_, "#" x $1)'

第一部分,直到 Perl 脚本,将产生如下输出

  23 ASCII C program text
  12 ASCII text
  10 ELF 64-bit LSB relocatable, x86-64, version 1
   3 ASCII English text
   1 ELF 64-bit LSB shared object, x86-64, version 1

Perl 脚本将删除尾随的换行符chomp,然后将数字挑选到 中$1。然后,它printf()打印出数字、文件类型以及#数字指示的字符数。

最终输出将类似于

23  ASCII C program text                              : #######################
12  ASCII text                                        : ############
10  ELF 64-bit LSB relocatable, x86-64, version 1     : ##########
3   ASCII English text                                : ###
1   ELF 64-bit LSB shared object, x86-64, version 1   : #

相关内容