Script to find files in subdirectories - windows

I need a script that will find and get me all files in all subdirectories (and leave them in the folder structure as they are now). I know how to find and print that files:
find . -name "something.extension"
The point is, in those directories are lots files that was used before, but I don't want to get those, so the script should only find me files that matches some kind of path pattern which is:
xxx/trunk/xxx/src/main/resources
xxx is different everytime, and after resources there are still some folders that directories are different based on xxx.
Every top xxx folder contains folder named 'tags' (the same level as trunk) that stores previous releases of module (and every release has files that name I am looking for, but I don't want outdated files).
So I want to find all that files in subdirectories of that path pattern that I specified and copy to new location but leave folder structure as it is right now.
I am using Windows and cygwin.
Update
I combined answer commands that 'that other guy' posted below, and it works. Just to be clear I have something like this:
find */trunk/*/src/main/resources -name "something.extension" -exec mkdir -p /absolute/target/path/{} \; -exec cp {} /absolute/target/path/{} \;
Thanks.

Instead of searching under the entire current directory (.), just search under the directories you care about:
find */trunk/*/src/main/resources -name "something.extension"

Related

Copy whole directory but exclude all folders and subfolders with certain name

I'm not allowed to use rsync on the cluster I'm working on so I need to use cp. I want to copy a large directory including all files and subfolders etc. but without any folders that have the name "outdir".
I tried cp -r -v ./!(outdir) ../target-directory/
but it still copies all folders and contents in deeper directories with the name outdir. It only included the outdir folders in the highest directory.
I also tried cp -r ./*/!(outdir) ../target-directory/ but that one copied all files into the folder without keeping any hirarchy or folders etc.
I also tried certain find commands but it didn't work, but maybe I was just doing something stupid. I'm a beginner with bash so if you could explain your answer and what the flags etc. do that would really be helpfull, I've been trying forever now, on what I think shouldn't be that hard to do.
Instead of cp, you can use tar with option --exclude to control what you want copied or not.
The full command is:
tar --exclude="outdir" -cvpf - . | (cd TARGET_DIRECTORY; tar -xpf -)
So any path that contains the "outdir" pattern will be excluded.
Without the --exclude option, it will copy the entire structure of your current directory under TARGET_DIRECTORY.
You can replace the . in the first tar by your desired source directory.

LibreOffice: recursively convert documents in folders and subfolders

I have stored many files in the doc format which I can only open with libreoffice on my mac.
The command:
./soffice --headless --convert-to docx --outdir /home/user ~/Downloads/*.doc
does exactly what it should: it converts all the *.doc files to libreoffice *.docx file.
My problem is that I have folders and subfolders with these files.
Is there any way to search through all the folders from a starting directory and to let "soffice" do its job in each of these folders, storing the new versions (*.docx) exactly where the original (*.doc) was found.
Unfortunately, I am not well-versed in apple script or in terminal to make this work. Yet there are 8000 doc files in hundreds and hundreds of folders that require the update to docx.
Thanks for your help.
Is there any way to search through all the folders from a starting directory and to let "soffice" do its job in each of these folders, storing the new versions (.docx) exactly where the original (.doc) was found.
This can actually be done in Terminal using a find command:
find '/path/to/directory' -type f -iname '*.doc' -execdir /Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to docx '{}' \;
In the example command above, change '/path/to/directory' to the actual pathname of the target directory that contains the subdirectories containing the .doc files.
What this find command does, in brief, is it finds all .doc files within the hierarchical directory structure of the '/path/to/directory' and executes the command in each subdirectory within containing the .doc files and converts each one in place in its subdirectory.
Notes:
Always insure you have proper backups before running commands in Terminal and the commands as typed will produce the wanted behavior!
This command assumes no .docx files already exist of the same name as the .doc files in the subdirectories, as it automatically overwrites any existing .docx files of the same name as the .doc files. As far as I can tell, the soffice command does not provide an option not to overwrite existing files. If this is going to be an issue, then a different solution will be necessary.

How to Copy Files Without Overwriting Any Files in Bash Script

I am trying to write a script that finds all my files that are .jpg, and copies them do a new directory. It currently looks like this:
find ~/Pictures -iname \*.jpg -exec cp {} ...newDirectory \;
The problem is that some of my older files have the same name as newer files, when the IMG_#### reset back to 0001 and started counting again.
Is there a way to find the .jpgs and copy without overwriting the files? Ideally giving them a new name in the process.
EDIT
I ended up learning about rsync, which in its own way does exactly what I was looking for. Thanks for the help!
Use -n parameter for cp, that means: do not overwrite an existing file.
To prevent identical names, you could just name all of them unique.
Example:
$ touch screenshot.jpg
$ cp screenshot.jpg screenshot-$(date "+%s").jpg
So basically, mass rename the new files you want to copy to the same name+date.
That will make them different from what's already there, sice the older ones are unnamed or (if you repeat this later) will have different dates.

Bash Script: find command getting stuck

I'm currently writing a bash script wherein a portion of it needs to be able to look at a bunch of directory hierarchies and spit out two text files each containing a list of the directories and all the files, respectively, in the given directory.
As I understand the following should do the trick:
find $directory -type d >> alldirs.txt
where directory is assigned different directory path names since I'm supposed to check a number of them.
I have a for loop the iterates through my list of directories and uses the above function to complete my task. The above command gets to a certain point and then it gets stuck. When I investigated the issue it seemed like it would get to a directory that's empty and then it get stuck. And or it would actually start looking for directories that don't exist in the first place then it would get stuck. Any ideas?
Is there something I'm missing? Or did I understand how that works incorrectly? Is there a better alternative?
You haven't said $directory is a name. Without it, bash will complain that "find: $directory: No such file or directory"
For example:
find . -iname $directory -type d >> alldirs.txt
Note: The above will start searching in the current directory, specified by the "."
Change it to whatever directory you wish e.g. /home/mys.celeste
I had similar issue: find / -name blahblah stuck somewhere
When debugging I tried to search in all root directories like/tmp, /var, /sbin, /user and so on. And found that it is stuck on /media.
In /media I had RHEL repo mounted. So afterunmount - find continue to work normally.

Copying multiple files with same name in the same folder terminal script

I have a lot of files named the same, with a directory structure (simplified) like this:
../foo1/bar1/dir/file_1.ps
../foo1/bar2/dir/file_1.ps
../foo2/bar1/dir/file_1.ps
.... and many more
As it is extremely inefficient to view all of those ps files by going to the
respective directory, I'd like to copy all of them into another directory, but include
the name of the first two directories (which are those relevant to my purpose) in the
file name.
I have previously tried like this, but I cannot get which file is from where, as they
are all named consecutively:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Where ../plots is the folder where I copy them. However, they are now of the form file.ps.~x~ (x is a number) so I get rid of the ".ps.~*~" and leave only the ps extension with:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Then, as the ps files have hundreds of points sometimes and take a long time to open, I just transform them into jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
This is not really a working bash script as I have to change the directory manually.
I guess the best way to do it is to copy the files form the beginning with the names
of the first two directories incorporated in the copied filename.
How can I do this last thing?
If you just have two levels of directories, you can use
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
This goes over each ps file, and hard links them to the current directory with the /s replaced by _. Use cp instead of ln if you intend to edit the files but don't want to update the originals.
For arbitrary directory levels, you can use the bash specific
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
But are you sure you need to copy them all to one directory? You might be able to open them all with yourreader */*/*.ps, which depending on your reader may let browse through them one by one while still seeing the full path.
You should run a find command and print the names first like
find . -name "file_1.ps" -print
Then iterate over each of them and do a string replacement of / to '-' or any other character like
${filename/\//-}
The general syntax is ${string/substring/replacement}. Then you can copy it to the required directory. The complete script can be written as follows. Haven't tested it (not on linux at the moment), so you might need to tweak the code if you get any syntax error ;)
for filename in `find . -name "file_1.ps" -print`
do
newFileName=${filename/\//-}
cp $filename YourNewDirectory/$newFileName
done
You will need to place the script in the same root directory or change the find command to look for the particular directory if you are placing the above script in some other directory.
References
string manipulation in bash
find man page

Resources