문제

I have to write a shell script that takes the name of a directory and then searches all the files in it and in all the subdirectories and computes the medium number of lines . Here is what I tried :

#!/bin/sh

if [ $# -eq 0 ] #  check if a directory was pass as argument 
then
    echo "The call requires a directory name ! ";
    exit 1
fi

dirname=$1  # save the directory name
if [ ! -d $dirname ]  # check if it is a valid directory 
then
    echo $dirname is not a directory
    exit 1
fi

files_number=0    # the total number of files
files_lines_nr=0  # the total number of lines of the files

for fis in ` find $dirname -type f ` # loops the files in all the directories
do
    lines=` wc -l <$fis ` # get the number of lines in a file
    files_number=` expr $files_number + 1 ` # counts the number of files
    files_lines_nr=` expr $files_lines_nr + $lines ` # updates the total number of lines
done
echo "The medium number of lines :" ` expr $files_lines_nr / $files_number ` 

If I pass the drectory hw1 which has 1 file test3 ad 1 subdirectory -> that contains test2 and test1 files i get the value 7(the number of lines in file test2) twice. I made some more echos and here are the results:

0  in file tema1/test1~ 
0  in file tema1/test3~ 
7  in file tema1/subhw1/test2~  //why ?
7  in file tema1/subhw1/test2  // correct number of lines
11  in file tema1/test3  // correct number of lines
5  in file tema1/test1  // correct number of lines
Total number of lines :30  // incorect computes 7 twice
The medium number of lines : 5 // incorect there are only 3 files ,he counts 6.

Thanks !

도움이 되었습니까?

해결책

Since ~ files will come back the moment you clik the "Save" button in your editor, you might want to consider systematically excluding them and not simply removing the ones that are present now. This way your shell script will be more useful over time. You can do this using the find command. Here is an example:

find . -type f -and \( -name "*~" -prune -or -print \)

It says that two things must be true: It must be a regular file, and it must either be the case that it ends with a ~, in which case find will prune the result (i.e. not print it), or it gets printed.

The slightly less readable, POSIX-compliant version of this is:

find . -type f \( -name "*~" -prune -o -print \)

However, different editors have different naming schemes for temporary / backup files. Vim uses .filename.swp, Emacs uses #filename# and GEdit uses filename~ to name a few. For a truly versatile script, you may want to consider supporting these as well:

find . -type f \( -name "*~" -prune -o \
                  -name "*#" -prune -o \
                  -name "*.swp" -prune -o -print \)

다른 팁

It seems that within your directories you have tmp files which have a ~ postfix.

If you first run:

  rm tema1/test1~
  rm tema1/test3~
  rm tema1/subhw1/test2~

and then run your script everything should be correct.

Looks like you are calculating the mean not the median, be sure which you want.

~ files are backup files created by editors. They are ordinary files, so your program is counting the lines from them.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top