Find all files pattern with total size - linux

In order to find all logs files with a pattern from all subdirectories I used the command :
du -csh *log.2017*
But this command does not search in subdirectories. Is there any way to get the total size of all files with a pattern from all subdirectories?

This will do the trick:
find . -name *log.2017* | xargs du -csh

find . -name *log.2017* -type f -exec stat -c "%s" {} \; | paste -sd+ | bc

you can use find command
find /path -type f -name "*log.2017*" -exec stat -c "%s" {} \; | bc
It will do the search recursively.

Related

Linux find command get all text in the file and print file path

I need to get all the texts in the matching file in the folder. However, at the same time need to get the matching file path as well. How can I get the matching file path as well using the following command.
find . -type f -name release.txt | xargs cat
try
find . -type f -name release.txt -exec grep -il {} \; | xargs cat
Skip xargs, just do:
find . -type f -name release.txt -exec sh -c 'echo "$1"; cat "$1"' _ {} \;

Using find and grep in a specifc file in a specific directory

I have the following directory structure:
./A1
./A2
./A3
./B
./C
In each one of the A* directories I have:
./A*/logs
./A*/test
in the logs directory I have:
./log-jan-1
./log-jan-2
./log-feb-1
How do I grep for a string in all January logs in the A directories?
I tried this, but it did not find the string although it is present in the log files:
find . -type d -name 'A*' print | xargs -n1 -I PATH grep string - PATH/logs/log-jan*
What am I doing wrong?
Why don't you simply use
grep string ./A*/logs/log-jan*
?
If it is not a typo, you should use -print (or -print0) instead of print.
But as find + xargs + grep constructs are hard to debug, you should test in sequence :
find . -type d -name 'A*' -print
find . -type d -name 'A*' -print0 | xargs -0 -n1 -I PATH echo grep string - PATH
and finally :
find . -type d -name 'A*' -print0 | xargs -0 -n1 -I PATH grep string - PATH/logs/log-jan*
In you use case, -print and -print0 should give same results, but for having been burnt with -print, I always use -print0 before xargs

How to convert some files from dos format to unix

I know how to change file format from dos to unix by use dos2unix, but how can I change ALL the files will under a directory tree. Can dos2unix change files recursively?
for example, I have some files like following:
TOPDIR
|
+-----dir1
| |
| +---file1,file2, file3
|
+-----dir2
|
+---file4,file5
How can I change them in one time, or use some shell scripts?
better to do find /path -type -f -exec dos2unix '{}' \;
find /path -name '*' -type f -exec dos2unix {} \;
dos2unix -k `find . -type f`
find . -type f -exec dos2unix -k '{}' \;
find . -type f -print | xargs dos2unix -k
Any of above command can be used from TOPDIR

Find all files matching 'name' on linux system, and search with them for 'text'

I need to find all instances of 'filename.ext' on a linux system and see which ones contain the text 'lookingfor'.
Is there a set of linux command line operations that would work?
find / -type f -name filename.ext -exec grep -l 'lookingfor' {} +
Using a + to terminate the command is more efficient than \; because find sends a whole batch of files to grep instead of sending them one by one. This avoids a fork/exec for each single file which is found.
A while ago I did some testing to compare the performance of xargs vs {} + vs {} \; and I found that {} + was faster. Here are some of my results:
time find . -name "*20090430*" -exec touch {} +
real 0m31.98s
user 0m0.06s
sys 0m0.49s
time find . -name "*20090430*" | xargs touch
real 1m8.81s
user 0m0.13s
sys 0m1.07s
time find . -name "*20090430*" -exec touch {} \;
real 1m42.53s
user 0m0.17s
sys 0m2.42s
Go to respective directory and type the following command.
find . -name "*.ext" | xargs grep
'lookingfor'
A more simple one would be,
find / -type f -name filename.ext -print0 | xargs -0 grep 'lookingfor'
-print0 to find & 0 to xargs would mitigate the issue of large number of files in a single directory.
Try:
find / -type f -name filename.ext -exec grep -H -n 'lookingfor' {} \;
find searches recursively starting from the root / for files named filename.ext and for every found occurrence it runs grep on the file name searching for lookingfor and if found prints the line number (-n) and the file name (-H).
I find the following command the simplest way:
grep -R --include="filename.ext" lookingfor
or add -i to search case insensitive:
grep -i -R --include="filename.ext" lookingfor

how to find files containing a string using egrep

I would like to find the files containing specific string under linux.
I tried something like but could not succeed:
find . -name *.txt | egrep mystring
Here you are sending the file names (output of the find command) as input to egrep; you actually want to run egrep on the contents of the files.
Here are a couple of alternatives:
find . -name "*.txt" -exec egrep mystring {} \;
or even better
find . -name "*.txt" -print0 | xargs -0 egrep mystring
Check the find command help to check what the single arguments do.
The first approach will spawn a new process for every file, while the second will pass more than one file as argument to egrep; the -print0 and -0 flags are needed to deal with potentially nasty file names (allowing to separate file names correctly even if a file name contains a space, for example).
try:
find . -name '*.txt' | xargs egrep mystring
There are two problems with your version:
Firstly, *.txt will first be expanded by the shell, giving you a listing of files in the current directory which end in .txt, so for instance, if you have the following:
[dsm#localhost:~]$ ls *.txt
test.txt
[dsm#localhost:~]$
your find command will turn into find . -name test.txt. Just try the following to illustrate:
[dsm#localhost:~]$ echo find . -name *.txt
find . -name test.txt
[dsm#localhost:~]$
Secondly, egrep does not take filenames from STDIN. To convert them to arguments you need to use xargs
find . -name *.txt | egrep mystring
That will not work as egrep will be searching for mystring within the output generated by find . -name *.txt which are just the path to *.txt files.
Instead, you can use xargs:
find . -name *.txt | xargs egrep mystring
You could use
find . -iname *.txt -exec egrep mystring \{\} \;
Here's an example that will return the file paths of a all *.log files that have a line that begins with ERROR:
find . -name "*.log" -exec egrep -l '^ERROR' {} \;
there's a recursive option from egrep you can use
egrep -R "pattern" *.log
If you only want the filenames:
find . -type f -name '*.txt' -exec egrep -l pattern {} \;
If you want filenames and matches:
find . -type f -name '*.txt' -exec egrep pattern {} /dev/null \;

Resources