Let's say I have a 100 file like this 1.txt ....100.txt. Now I want to remove the .txt and calculate mean of the filename (since they are number). I looked into this Linux: remove file extensions for multiple files but still little confuse.
CodePudding user response:
You could use basename <path_to_file> <extension>
to strip away the directory part and extension, which would leave you with only the number.
Example:
#!/bin/bash
shopt -s extglob # extended globbing
filecount=0
sum=0
for file in some_dir/ ([0-9]).txt # loop over the files (using extended globbing)
do
num=$(basename "$file" .txt) # strip away dir and extension
(( sum = num )) # sum up the numbers
(( filecount )) # count the number of files
done
mean="NaN" # used if filecount is 0
if (( filecount > 0 ))
then
# calculate mean with 2 digits of precision
mean=$(echo "scale=2;$sum/$filecount" | bc)
fi
echo "$mean"
CodePudding user response:
Let's create some sample files:
$ for i in {1..10}; do touch "$RANDOM.txt"; done
$ ls
15158.txt 15964.txt 17123.txt 21123.txt 22209.txt 29456.txt 29826.txt 4168.txt 4287.txt 6787.txt
Now, store the filenames in an array, build up the expression as a string, and send it to a single bc
invocation:
files=(*.txt)
expr="(0"
for f in "${files[@]}"; do expr =" ${f%.txt}"; done
expr =") / ${#files[@]}"
echo "$expr"
echo "scale=3; $expr" | bc
outputs
(0 15158 15964 17123 21123 22209 29456 29826 4168 4287 6787) / 10
16610.100
More tersely:
join() { local IFS=$1; shift; echo "$*"; }
files=(*.txt)
printf -v expr "(%s)/%d" "$(join "${files[@]%.txt}")" ${#files[@]}
echo "$expr"
echo "scale=3; $expr" | bc
(15158 15964 17123 21123 22209 29456 29826 4168 4287 6787)/10
16610.100
CodePudding user response:
I'd do something like this
numbers=`ls | sed 's/.txt//g' | xargs`
echo $numbers
should show "1 2 3 .... 100"
sum=0; count=0
for i in $numbers; do
sum=$(echo "$sum $i" | bc)
((count ))
done
avg=$(echo "$sum / $count" | bc)
echo $avg