How to script to go to the deepest folder directory from parent directory to execute a command? - linux

I am trying to automate converting .vmx to .ova by ovftool, and these .vmx files are generated from ghettoVCB. So I am writing a script to get converting automation working.
My question is how do I write a shell script that goes through each directory from a parent_directory and executes a command in each directory? Or could move everything from the deepest folder to parent_directory? (This solution may take time consuming to move those files from the deepest folder to parent_directory).
The directory structure is as follows:
parent_directory/automation/automation-2016-04-18_19-08-32/automation.vmx
parent_directory/bulls/bulls-2016-04-18_18-28-57/bulls.vmx
Here is another structure layout
parent_directory
automation
automation-2016-04-18_19-08-32
automation.vmx
bulls
bulls-2016-04-18_18-28-57
bulls.vmx
The name of subfolders from parent_directory does not follow patterns. Could be any name.
The folder "automation-2016-04-18_19-08-32" is the name of subfolder + date + time.

Approach 1
move everything from the deepest folder to parent_directory
This command will search subdirectories of the current directory, find all .vmx files, and move them to the current directory:
find . -type f -name '*.vmx' -exec mv {} . \;
Approach 2
write a shell script that goes through each directory from a parent_directory and executes a command in each directory
The following command will search for every subdirectory of the current directory and execute command in it:
find . -type d -execdir command \;
If you want to run command in every directory that contains .vmx files and supply the names of those .vmx files as arguments to command, then run:
find . -type f -name '*.vmx' -execdir command {} +
Alternatively, suppose we want to run the command once for each .vmx file that we find:
find . -type f -name '*.vmx' -execdir command {} \;

Related

Linux find command explanation

Can someone explain me what does this command do and if I want to try the same thing using git, how should I modify this command?
find . -name CVS -print -exec rm -fr {} \;
This command looks in your current working directory for any directories or files named "CVS" and prints the full path. Then executes a forced recursive removal for each result returned by the find command.
Since there is no filetype present in the name, this command will remove any directory, within your current working directory, named CVS, including all subdirectories and files housed within.

Recursively find ".sh" file and then execute my .sh file on that path

I have a folder which contains sub sub folders and some folders contains .sh file. I want to execute my .sh file in that path where I see a .sh file. I tried
find . -name '*.sh'
./folder 1/folder 2/run.sh
./folder3/run.sh
./folder 4/run.sh
./folder5/run.sh
This find function is working correctly. Now I have another .sh file which I want to execute on .sh file path. I tried
find . -name '*.sh' /home/cool/Desktop/followup.sh {} ;
where followup.sh is my file. The command is getting executed at current directory . but it is not getting executed on run.sh file path.
I am new to bash scripting. What command or commands would I issue? Note that there are spaces in Folder name.
find <parent-directory where all sub-folders with run.sh are located> -name '*.sh' -execdir /home/cool/Desktop/followup.sh {} \;

Linux backup all files with known extensions with timestamps

I want to backup all files with a given extension in a directory but I want them to be with timestamps.
Given a directory:
Sample/ with multiple subdirectory and a subfolder name BACKUPS.
cd Sample
find . -name '*.xml' -exec cp {} BACKUPS \;
Say I have multiple xml files in this Sample folder and I want them to be copied to the BACKUPS folder but I want them to be timestamp
say..
text.xml.20171107
conf.xml.20171107
I am able to backup the files but I could not figure out how to append a timestamp to the files using the find command.
You could try this:
find . -name '*.xml' -execdir cp {} "$PWD/BACKUPS/{}.$(date +%Y%m%d)" \;
As before, we use find . -name '*.xml' to locate all the files. However, in order to get rid of the names of subdirectories, we use -execdir instead of exec. This causes the specified command to be run from inside the subdirectory the current file is in and replaces {} by its base name.
This means we have to modify cp's second argument (the target filename). We now pass "$PWD/BACKUPS" to create an absolute path ($PWD is the current working directory). This way cp always targets the right directory, even when invoked from a subdirectory of Sample.
Finally, the filename we use is constructed from {}.$(date +%Y%m%d). $( ) runs the specified command and substitutes its output (the current date, in this case). This is done by the shell before find is invoked, so find just sees .../{}.20171107. The {} part is replaced by find itself just before it runs each cp.

Linux command to create the empty file called 'test1'

Enter a Linux command to create the empty file called 'test1' in the directory 'systems' (you are still in your home directory).
Assuming 'systems' is a subdirectory of the current directory:
touch systems/test1
Assuming that you only know that the directory 'systems' is some subdirectory in the directory tree of the current directory then: find . -name systems -type d -exec touch "{}/test1" \; Will create such a file. Alternately, so will find . -name systems -type d -execdir touch systems/test1 \; However, both will do so in every subdirectory named 'systems' in the current directory tree. We could limit that action to only the first, the last, or some other criteria, but the list of possible permutations is just too long.
You really have not provided enough information for us to provide a complete answer.

Search recursively for files in a parent directory in Linux

I am trying to list all the files in a parent directory and its subdirectories. However, I am running this command from another location. So, at first, I need to traverse to the directory (from where I want to run this command).
Please note that I am using the find command instead of ls because I also want to list down the absolute path for each file in front of it. This is not possible with the ls command.
here is what I am doing:
cd ../../../;cd level1_dir1;find $(pwd) . -name *.* -printf "%TY-%Tm-%Td\t%p\n"
This command does not show any output.
Here is the directory structure:
level1_dir1
this has multiple subdirectories:
level2_dir1
level2_dir2
....
level2_dir10
each of these subdirectories again have subdirectories and files inside them.
however, now if I do:
cd ../../../;cd level1_dir1/level2_dir1;find $(pwd) . -name *.* -printf "%TY-%Tm-%Td\t%p\n"
it will do the recursion properly for all the subdirectories in level2_dir1 and show output like:
date level1_dir1/level2_dir1/path/to/file/filename
so, I wanted to print out for all the level2 directories, this way (by using the wild character):
cd ../../../;cd level1_dir1/*;find $(pwd) . -name *.* -printf "%TY-%Tm-%Td\t%p\n"
but it prints out the results only for the first directory in level2 (that is level2_dir1)
how can I make it list down the files for all the subdirectories?
thanks.
How about this?
find ../../../level1_dir1 -printf "%TY-%Tm-%Td\t%p\n"
If you want all the files, you don't even need -name in the find command. If you don't want to see the directories and only the files, just add "-type f" before -printf.
Hope this helps...

Resources