linux: find common files from two directories with single command - linux

Dir1: [anyName]-test/target/surefire-reports/*.xml
Dir2: target/surefire-reports/*.xml
jenkins shell cmd i came up:
sh "jar -cMvf Test.zip target/surefire-reports/*.xml *-test/target/surefire-reports/*.xml "
only one directory exists ( dir1 or dir2), so the shell step always fails for no file or directory.
Any better idea to look for xml files, in single command, without failing ? (may be some regular expression) Thanks !

With GNU find:
find . -type f -regex '\./\([^/]*-test/\)?target/surefire-reports/[^/]*\.xml'\
-exec jar -cMvf Test.zip {} +
The -regex action matches the path of your regular (type -f) files. This will only add *.xml files from the surefire-reports directories, not from its subdirectories. If you want to include subdirectories, replace [^/]*\.xml with .*\.xml.
Alternative using glob patterns:
find target/surefire-reports *-test/target/surefire-reports -maxdepth 1 -type f\
-name '*.xml' -exec jar -cMvf Test.zip {} +
If you want to include subdirectories, remove -maxdepth 1.
Run both commands from the parent directory of target (your project dir).

Try:
cd <TOP DIRECTORY>
find . -type f -name "*unitTest.xml" -print | xargs jar -cMvf Test.zip
I put "*unitTest.xml since in Dir2 the J is in caps.
This way it will capture the JUnitTtest.xml files only if they exist.
So the results of the find command are used as arguments to the jar command. This is done by xargs. find does not care if the file is there or not, so no error.
Tested on bash.

Related

Copy recursive files of all the subdirectories

I want to copy all the log files from a directory which does not contain log files, but it contains other subdirectories with log files. These subdirectories also contain other subdirectories, so I need something recursive.
I tried
cp -R *.log /destination
But it doesn't work because the first directory does not contains log files. The response can be also a loop in bash.
find /path/to/logdir -type f -name "*.log" |xargs -I {} cp {} /path/to/destinationdir
Explanation:
find searches recursively
-type f tells you to search for files
-name specifies the name pattern
xargs executes commands
-I {} indicates an argument substitution symbol
Another version without xargs:
find /path/to/logdir -type f -name '* .log' -exec cp '{}' /path/to/destinationdir \;

How to rename files in different directories with the same name using find

I have files named test.txt in different directories like this
./222/test.txt
./111/test.txt
I want to rename all test.txt to info.txt
I've tried using this
find . -type f -iname 'test.txt' -exec mv {} {}info \;
I get test.txtinfo
Your idea is right, but you need to use -execdir instead of just -exec to simplify this.
find . -type f -iname 'test.txt' -execdir mv {} info.txt ';'
This works like -exec with the difference that the given shell command is executed with the directory of the found pathname as its current working directory and that {} will contain the basename of the found pathname without its path. Also note that the option is a non-standard one (non POSIX compliant).

Loop through a directory with any level of depth

I want to execute a command on all files present on all levels in the directory. It may have any number of files and sub directories. Even these sub directories may contain any number of files and subdirectories. I want to do this using shell script. As I am new to this field can any one suggest me a way out.
You can use the command "find" with "xargs" after "|"(pipe).
Example: Suppose that I want to remove all files that have ".txt" extension on "Documents" directory:
find Documents -iname *.txt |xargs rm -f
Helps?
You can use a recursive command that uses wildcard characters (*) like so:
for dir in ~/dev/myproject/*; do (cd "$dir" && git status); done
If you want to apply commands on the individual files you should use the find command and execute commands on it like so:
find yourdirectory -type f -exec echo "File found: '{}'" \;
What this does:
finds all the items in the directory yourdirectory
that have the type f - so are a file
runs an exec on each file
Use find:
find -type f -exec COMMAND {} \;
-f applies the command only to files, not to directories. The command is recursive by default.

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)

Changing all file's extensions in a folder using CLI in Linux

How to change all file's extensions in a folder using one command on CLI in Linux?
Use rename:
rename 's/.old$/.new/' *.old
If you have the perl rename installed (there are different rename implementations) you can do something like this:
$ ls -1
test1.foo
test2.foo
test3.foo
$ rename 's/\.foo$/.bar/' *.foo
$ ls -1
test1.bar
test2.bar
test3.bar
You could use a for-loop on the command line:
for foo in *.old; do mv $foo `basename $foo .old`.new; done
this will take all files with extension .old and rename them to .new
This should works on current directory AND sub-directories. It will rename all .oldExtension files under directory structure with a new extension.
for f in `find . -iname '*.oldExtension' -type f -print`;do mv "$f" ${f%.oldExtension}.newExtension; done
This will work recursively, and with files containing spaces.
Be sure to replace .old and .new with the proper extensions before running.
find . -iname '*.old' -type f -exec bash -c 'mv "$0" "${0%.old}.new"' {} \;
Source : recursively add file extension to all files
(Not my answer.)
find . -type f -exec mv '{}' '{}'.jpg \;
Explanation: this recursively finds all files (-type f) starting from the current directory (.) and applies the move command (mv) to each of them. Note also the quotes around {}, so that filenames with spaces (and even newlines...) are properly handled.

Resources