0

I encountered a problem while writing my bash script

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`

Output looks like this:

  ASCII text...                           : #######
  empty...                                : ####
  Bourne-Again shell script, ASCII text...: ##
  PDF document, version 1.4...            : #

What i am trying to do is put the dots only when the file type is longer than 40 not always. Example:

  ASCII text                              : #######
  empty                                   : ####
  Bourne-Again shell script, ASCII text...: ##
  PDF document, version 1.4               : #

Is there a way to do it?

Walter A
  • 19,067
  • 2
  • 23
  • 43
Adam
  • 99
  • 2
  • 8
  • 1
    The `file` utility doesn't read filenames from the stdin. the `find ... | file` is pointless. It will always check the filenames stored in the `$SAVEFILES` variable... – clt60 Apr 09 '17 at 08:11

2 Answers2

1

The awk solution of @PSkocik is very good.
Just for the record, you can do things (slower) without awk.

When you want to replace everything after the 37th pos when a string is longer than 40 pos, you can use

sed 's/\(.\{37\}\).\{3\}.\+/\1.../' <<< "$text"

Off-topic:
You can replace

  for ((i=0;i<$n;i++)); do 
     printf "%s" "#"
  done
  echo

with

   printf "%*.*s\n" $n $n '#' | tr ' '  '#'

EDIT:
Note that removing the cut is not possible with my solution, since the differences in strings can be after the 40th position and you want uniq lines in the output. When only the 38th pos is different you will get different output lines, so it would be better to replace the cut command with the sed command.

Walter A
  • 19,067
  • 2
  • 23
  • 43
0

Yo could use awk (should be faster and more portable than 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

Output:

ASCII text                              : #######
empty                                   : ####
Bourne-Again shell script, ASCII text...: ##
PDF document, version 1.4               : #
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142