Home > database >  How to remove file extension using linux and store first the filename
How to remove file extension using linux and store first the filename

Time:10-28

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
  •  Tags:  
  • bash
  • Related