数字を1文字(数字)と同じ値に置き換える

数字を1文字(数字)と同じ値に置き換える

すべてのファイルタイプの検索を使用して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を表現する方法」という主な質問に答えるには、次のようなシェルコマンドがあります。

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   : #

関連情報