Speedup find command - unix

I am getting file count and find size using same find command but currently running find twice as shown below. How to perform both operations in one line and eliminate one find?
file_cnt[$i]=$(find $dir_name -type f -ctime +$ctime1 -ctime -$ctime2 | wc -l)
file_size[$i]=$(find $dir_name -type f -ctime +$ctime1 -ctime -$ctime2 | xargs --no-run-if-empty --max-procs=2 du -s | awk '{sum += $1} ; END {printf "%.2f", sum/1024**2}')

try something like this
read "file_cnt[$i]" "file_size[$i]" << EOF
$(find $dir_name -type f -ctime +$ctime1 -ctime -$ctime2 | xargs --no-run-if-empty --max-procs=2 du -s | awk '{count++;sum += $1} ; END {printf "%d %.2f", count, sum/1024**2}')
EOF

I would suggest to use find to return the file sizes and awk to do the sum and the file count:
$ find $dir_name -type f -ctime +$ctime1 -ctime -$ctime2 -printf "%s\n" | awk '{s+=$1}{print NR,s}'

Related

Suffix subdirectory name with number of files underneath it

I have subdirectories a b c. For various obscure reasons, I would like to count all files recursively underneath these and only for maxdepth=1 mindepth=1 suffix this first layer of subdirectories with the file count down to the bottom of each subdirectory tree (no limit).
So if a and its subdirectories have 23 files, b...64 and c...82 I will end up with subdirectories renamed as
a_23
b_64
c_82
I have a routine to count recursively:
function count_all_files () {
echo "enter directory"
find "$1" -type f | wc -l
}
but am at a loss how to construct a find -exec operation to rename as I need.
Something like this pseudo code.
find . -type d -mindepth 1 -maxdepth 1 "*" -exec $(count_all_files {}) && [suffix dir name]
Grateful for thoughts. Needs to work with directories containing spaces too.
This seems to be working. I have amended it so it always makes a clean update eg if you add new files.
function label_subdirectories_number_files () {
for file in *_my_dir_count_* ; do rename 's/_my_dir_count_.*//g' "$file" ; done
find . -type d -mindepth 1 -maxdepth 1 -name '*' -exec bash -c 'cd {} \
&& number_of_files=$(find . -type f | wc -l) && directory=$(pwd) \
&& directory="${directory## }" && read -r number_of_files <<< "$number_of_files" \
&& new_directory="$directory""_my_dir_count_""$number_of_files" && \mv "$directory" "$new_directory" ' &> /dev/null 2>&1 \;
}
This variation does selected number of lower subdirectories too in case you want a quick eyeball test of lower level counts.
function label_subdirectories_number_files_many () {
echo "enter number of levels to scan"
for file in *_my_dir_count_* ; do rename 's/_my_dir_count_.*//g' "$file" &> /dev/null 2>&1 ; done
for zcount in $(seq 1 "$1") ; do
echo "level = $zcount out of $1 "
find . -type d -mindepth $zcount -maxdepth $zcount -name '*' -exec bash -c 'cd {} \
&& number_of_files=$(find . -type f | wc -l) && directory=$(pwd) \
&& directory="${directory## }" && read -r number_of_files <<< "$number_of_files" \
&& new_directory="$directory""_my_dir_count_""$number_of_files" && \mv "$directory" "$new_directory" ' &> /dev/null 2>&1 \;
done
}

How to calculate total size of all css,js and html pages separately uing shell script?

I have the following code in shell script
find -name "*.css" -exec -printf '%16f Size: %6s\n'
This gives me the file size of every css file. How do I modify this to get the added sum of all the file sizes ?
You could use awk:
find . -name "*.css" -type f -printf '%s\n' | awk '{ tot+=$0 } END { print tot }'
Or in pure bash:
total=0
while read -r s;
do
total=$(( total+s ))
done < <(find . -name "*.css" -type f -printf '%s\n')
echo $total
In 2 steps:
1) ll *css | tr -s " " > filename.txt
2) awk 'BEGIN {x=0} {x+=$5} END {print x}' filename.txt

Size of files in subdirectories

I would like to know if there is an easy way to compute the total size of files in subdirectories in unix? I am interested in all the .js files in a folder with subdirectories and I am trying to use du -ah and grep *.js but does not work. Any help is appreciated. thanks
find . -iname "*.js" -ls | awk '{sum += $7} END {print sum}'
I dont think there is a way with du, but you can use awk
This is for all java files:
> find . -name "*.java" | xargs du -a | awk '{sum+=$1}END{print sum}'
2774
so you can modify this to :
find . -name "*.js" | xargs du -a | awk '{sum+=$1}END{print sum}'
Try below command..... It will print the total at the end...
find . -name '*.js' -exec du {} \; | awk 'sum=sum+$1; END{print sum " total" }'
find . -name '*.js' -exec stat -c %s '{}' + | awk '{ sum += $0 } END { print sum }'

Unix script to recursively search a directory and sub directories to grep and print content between 2 patterns in file

I have some files in a directory and sub directories. I need to search all the files and print the file name and the content between 2 matching patterns in the file.
For e.g. lets say my file looks like below.
File1.txt:
Pattern1
ABCDEFGHI
Pattern2
dafoaf
fafaf
dfadf
afadf
File2.txt
Pattern1
XXXXXXXXX
Pattern2
kdfaf
adfdaf
fdafad
I need to get following output
File1.txt:
ABCDEGHI
File2.txt:
XXXXXXXX
and so on for all the files under directory and sub directories separated by new line.
This might work for you:
find . \
-type f \
-exec awk 'BEGING {print FILENAME ":"} /Pattern1/ { p=1 ; next } /Pattern2/ {p=0} p==1 {print $0} END {print ""}' \{\} \;
Note, this prints the FILENAME, even if Pattern1 was not found!
This will work for you :
Create this shell script as my_grep.sh
#!/bin/sh
grep -nH "Pattern" $1 >>temp
if [ `grep -c $1 temp` -eq 2 ]; then
limits=`grep $1 temp | cut -f2 -d:`
lower_limit=`echo $limits | cut -f1 -d" "`
upper_limit=`echo $limits | cut -f2 -d" "`
echo "$1:"
head -`expr $upper_limit - 1` $1 | tail -`expr $upper_limit - $lower_limit - 1`
fi
Use find command to search files and fire this schell script:
$ find ./test -type f -exec ./my_grep {} \;
./test/File1.txt:
ABCDEFGHI
./test/File2.txt:
XXXXXXXXX

Command to get list of files with ".log" extension and "JB_" in name and "ERROR:" in the body of log file(not name of log file) in UNIX

I tried this below command
ls -1 /fbrms01/dev/Logs/JB_*.log | find . -type f | xargs grep -l "ERROR:" > /fbrms01/dev/Logs/text_JB.txt
for these below files
./JB_CreateFormat_2013.03.18_08.27.49.log
./JB_CreateFormat_2013.03.18_17.21.31.log
./JB_ExtReservationDetail_2013.03.15_13.06.26.log
./JB_Report_Master_2013.03.18_09.53.38.log
./StoredProcessServer/ApplyTemplate_2013.02.15.log
./StoredProcessServer/ApplyTemplate_2013.03.20.log
./StoredProcessServer/AuthView_2012.08.21.log
./StoredProcessServer/AuthView_2013.02.15.log
./StoredProcessServer/BookPace_2013.01.29.log
I'm getting all the files with .log and ERROR: in the output file but I want only files which starts with JB_ and ending with .log.
Any help??
find /fbrms01/dev/Logs -type f -name 'JB_*.log' -exec grep -l "ERROR:" {} \; > /fbrms01/dev/Logs/text_JB.txt

Resources