Get list of files that contain given text within directory given by pattern - linux

I want to get a list of files that contain a given text within my file-system. Furthermore only files should be considdered that are located in a directoy given by a pattern.
So let´s say I have a number of directories called myDir within my filelsystem as shown here:
/usr
/myDir
/tmp
/myDir
/anotherDir
Now I want to get all the files within those directories that contain the text.
So basically I need to perform these steps:
loop all directories names myDir on the whole file-system
for every directory within that list get the files that contain the search-string
What I tried so far is find /etc /opt /tmp /usr /var -iname myDir -type d -exec ls -exec grep -l "SearchString" {} \;
However this doesn´t work as the results of find are directories which I may not use as input for grep. I assume I have to do one step in between the find and the grep but can´t find out how to do this.

I think I got it and will show you a little script that achieves what I need:
for i in $(find / -type d -iname myDir) do
for j in $(find "$i" -type f) do
grep "SearchString" "$j"
done
done
This will give me all the files that contain the SearchString and are located in any of the folders named myDir.

Related

copying files from etc ending with digit to test1 directory

I'm new to linux and as an exercice I need to copy the "etc" files that end with a digit from home directory to the test1 directory
(with one command).
I tried this but it dosn't work
find /etc -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
this should work for your home directory files ending with digit
mv `ls . |grep -Eo "^.*[0-9]$"` your-directory
lets says in the current directory you have some files like ofjweifhwef9 or kfhiofeh8 ( files ending with digit)
so ls will list them.
this grep expression "^.*[0-9]$"` will find only files ending with digit. ( because in your home directory system wont allow to have a file like this "/etc/somefile123")
and then mv will move those files to your-directory
note :- if grep cannot find the files ending with number you will see an error ofcourse because mv needs 2 operands but since it wasn't there so error.
mv: missing destination file operand after './your-directory'
It is probably because /etc is a link in the system that you're using, and find doesn't seem to consider it a path until you add an extra / at the end. Try this instead:
find /etc/ -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
Notice the /etc/ instead of /etc. I get the same behavior on my Mac where /etc is a link to another directory.
Of course, also make sure that you have files which names end on a digit under the /etc/ directory tree. I have none in my mac. You should get some files when you run:
find /etc/ -type f -iname "*[3-9]"
If you don't, you don't have any files to copy. You may also try: find /etc/ to see all files under the directory tree.
Finally, you may want to add the option: -depth 1 if you only want to copy the files in the /etc/ directory, as opposed to all the files that match in the directory tree under /etc/.

How can I remove specific directories that all start with a common letter?

I have many EC2 instances in a folder that I need to delete. Using -delete doesn't work because the directories are not empty. I tried looking for a way to get -rmdir -f to work with no success. The instance folders are all started with "i-" which led me to add wildcard "i-*" like that to get it to delete all directories starting with those characters. How can I manage to do this? the directories will never be empty either.
Assuming your current dir is the folder in question, how about:
find . -type d -name 'i-*'
If that lists the directories you want to remove, then change it to:
find . -type d -name 'i-*' -exec rm -r {} \;
In the command line interface/shell/born again shell/etc...
rm -r i-*
will remove ANY and ALL contained file(s) or directory(s) with subfiles and sub directories (recursive = -r) where the name begins with "i-" .
To delete the directories matching the pattern graphene-80* directly under /tmp, use
rm -rf /tmp/graphene-80*/
Here, the trailing / ensures that only directories whose names match the graphene-80* pattern are deleted (or symbolic links to directories), and not files etc.
To find the matching directories elsewhere under /tmp and delete them wherever they may be, use
find /tmp -type d -name 'graphene-80*' -prune -exec rm -rf {} +
To additionally see the names of the directories as they are deleted, insert -print before -exec.
The two tests -type d and -name 'graphene-80*' tests for directories with the names that we're looking for. The -prune removes the found directory from the search path (we don't want to look inside these directories as they are being deleted), and the -exec, finally, does the actual removal by means of calling rm.

Recursive find and copy to other directory

I need to find all files in a directory and it's subdirectories, but I need to keep directory structure. For example there is a file
/media/subdir1/subdir2/file.jpg
and I want to copy it to
/new-media/subdir1/subdir2/file.jpg
and the same to all files inside /media/ directory. And by the way, directories inside /new-media/ must be created if not exist.
if I use
find /media/ -name '*.jpg' -exec cp /new-media/ ????? {} \;
how can I get all subdirectories inside /media/?
The above will get you everything in /media, but to get exactly what you want you probably want to use something like:
Method 1: Copy only what you need recursively, per your requirements:
mkdir ../media2; find . -name "*.jpg" -exec cp -r --parents {} ../media2 \;
I ran this from inside the directory you want to search recursively. It does a couple things:
1 - create the new destination directory
mkdir ../media2
2 - then finds all files ending with ".jpg" recursively.
find . -name "*.jpg"
3 - uses -exec to pass the copy command to each file returned to find as a match, and subs that in as the first argument (which with the syntax of cp, is going to be your source file):
-exec cp -r --parents {} ../media2 \;
the "--parents" flag retains existing directory structure and recursively creates subsequent parent directories. Super useful right?
Method 2: there might be a better way to do this with xargs, but the above ended up being the most simple method imho. That said, if you want to think outside the box, you could simply copy the entire directory over recursively, then remove anything NOT ending with ".jpg" with something like:
cp -r media media2; find ./media '!'-name "*.jpg" -type f | xargs rm
I think this is what you want:
cp -r /media /new-media
-R, -r, --recursive
copy directories recursively
Hope this helps.

Bash Command for Finding the size of all files with particular filetype in a directory in ubuntu

I have a folder which contains several file types say .html,.php,.txt etc.. and it has sub folders also .Sub folders may contain all the file types mentioned above.
Question1:- I want to find size of all the files having the file type as '.html' which are there in both root directory and in sub- directories
Question2:- I want to find size of all the files having the file type as '.html' which are there only in root directory but not in sub folders.
I surfed through the internet but all i am able to get is commands like df -h, du -sh etc..
Are there any bash commands for the above questions? Any bash scripts?
You can use the find command for that.
#### Find the files recursively
find . -type f -iname "*.html"
#### Find the files on the r
find . -type f -maxdepth 1 -iname "*.iml"
Then, in order to get their size, you can use the -exec option like this:
find . -type f -iname "*.html" -exec ls -lha {} \;
And if you really only need the file size (I mean, without all the other stuff that ls prints):
find . -type f -iname "*.html" -exec stat -c "%s" {} \;
Explanation:
iname search of files without being case sensitive
maxdepth travels subdirectories recursively up to the specify level (1 means only the immediate folder)
exec executes an arbitrary command using the found paths, where "{}" represents the path of the file
type indicates the type of file (a directory is a file in Linux)

Merging Sub-Folders together, Linux

I have a main folder "Abc" which has about 800 sub-folders. Each of these sub-folders contains numerous files (all of the same format, say ".doc"). How do I create one master folder with all these files (and not being distributed into subfolders). I am doing this on a Windows 7 machine, using cygwin terminal.
The cp -r command copies it but leaves the files in the sub-folders, so it doesn't really help much. I'd appreciate assistance with this. Thank you!
Assuming there could be name collisions and multiple extensions, this will create unique names, changing directory paths to dashes (e.g. a/b/c.doc would become a-b-c.doc). Run this from within the folder you want to collapse:
# if globstar is not enabled, you'll need it.
shopt -s globstar
for file in */**; do [ -f "$file" ] && mv -i "$file" "${file//\//-}"; done
# get rid of the now-empty subdirectories.
find . -type d -empty -delete
If you can guarantee unique names, this will move the files and remove the subdirectories. You can change the two .s to the name of a folder and run it from outside said folder:
find . -depth \( -type f -exec mv -i {} . \; \) -o \( -type d -empty -delete \)
This may not be the most elegant or efficient way to do it, but I believe it'd accomplish what you want:
for file in `find abc`
do
if [ -f $file ]
then
mv $file `basename $file`
fi
done
Iterate through everything in abc, check if it's a file (not a directory) and if it is then move it from its current location (eg abc/d/example.txt) to abc/
Edit: This would leave all the subfolders in place (but they'd be empty now)

Resources