How to send files from folder recursively to command in linux console? - linux

I want to generate docs for coffee-script files. I want to use Docco.
When i use:
docco client/coffee/*
it throws error. I think because folders are in file list.
When i use:
docco client/coffee/*.coffee
it cant' find some files, because i havent anithing in root folder.
How to give all *.coffee files recursievly to command in console?

There are several ways to do it
$ find client/coffee/ -name '*.coffee' -exec docco {} +
$ find client/coffee/ -name '*.coffee' | xargs docco
However, note that the latter way does not work if there is space in file name, unless you use find -print0 with combination of xargs -0.
Additionally, if you are using bash, you can use **/*.coffee with setting shopt -s globstar

Related

How do I write a command to search and remove files, even in cases where the files can't be found?

I’m using Amazon Linux with the bash shell. I want to find and remove some PDF files in a single line, so I tried
find /home/jboss/.jenkins/jobs/myco/workspace/ebook/ -name '*.pdf' | xargs rm
This works fine if there are PDF files. But if there are none, I get the error
rm: missing operand
Is there any way to write the above statement in a single line so that it will not fail, even if there are no files to remove?
This can easily be achieved using the -r flag to xargs.
I also recommend using "special character tolerant" version:
find /home/jboss/.jenkins/jobs/myco/workspace/ebook/ -name '*.pdf' -print0 | xargs -0 -r rm
Have you tried doing it all within the find command?
find /home/jboss/.jenkins/jobs/myco/workspace/ebook/ -name '*.pdf' -exec rm -f {} \;
I've always used the construct above though I believe you can also use the switch -delete which may be a bit more efficient. If you do use it remember to put -delete at the end as find is evaluated left to right as an expression.
You don't even need find, you can simply use rm, it supports basic pattern matching. Just do the following:
rm -f path/*.pdf

find and remove multiple file using linux command

I have a directory named classes which contains a lot of sub-directories -
classes
|-security
|-registration
|-service
....
Each of these directory contains a lot of java files and their compiled classes files. I want to remove all the class file.
Going to classes directory I can list out all the class file using find command -
$ find . -name *.class
Is there any command in linux to remove all the classes file under the classes directory.
The usual answer uses the -exec option of find:
find . -name "*.class" -exec rm {} \;
Be sure to quote the wildcard, to ensure that it is passed into find (rather than globbed by the shell, first).
For further discussion, see these questions:
Command line: piping find results to rm
Linux why can't I pipe find result to rm?
Use xargs with pipe lining -
$ find . -name *.class | xargs rm *

Unix: traverse a directory

I need to traverse a directory so starting in one directory and going deeper into difference sub directories. However I also need to be able to have access to each individual file to modify the file. Is there already a command to do this or will I have to write a script? Could someone provide some code to help me with this task? Thanks.
The find command is just the tool for that. Its -exec flag or -print0 in combination with xargs -0 allows fine-grained control over what to do with each file.
Example: Replace all foo's by bar's in all files in /tmp and subdirectories.
find /tmp -type f -exec sed -i -e 's/foo/bar/' '{}' ';'
for i in `find` ; do
if [ -d $i ] ; then do something with a directory ; fi
if [ -f $i ] ; then do something with a file etc. ; fi
done
This will return the whole tree (recursively) in the current directory in a list that the loop will go through.
This can be easily achieved by mixing find, xargs, sed (or other file modification command).
For example:
$ find /path/to/base/dir -type f -name '*.properties' | xargs sed -ie '/^#/d'
This will filter all files with file extension .properties.
The xargs command will feed the file path generated by find command into the sed command.
The sed command will delete all lines start with # in the files (feed by xargs).
Command combination in this way is very flexible.
For example, find command have different parameters so you can filter by user name, file size, file path (eg: under /test/ subfolder), file modification time.
Another dimension of flexibility is how and what to change in your file. For ex, sed command allows you to make changes on file in applying substitution (specify via regular expressions). Similarly, you can use gzip to compress the file. And so on ...
You would usually use the find command. On Linux, you have the GNU version, of course. It has many extra (and useful) options. Both will allow you to execute a command (eg a shell script) on the files as they are found.
The exact details of how to make changes to the file depend on the change you want to make to the file. That is probably best scripted, with find running the script:
POSIX or GNU:
find . -type f -exec your_script '{}' +
This will run your script once for a group of files with those names provided as arguments. If you want to do it one file at a time, replace the + with ';' (or \;).
I am assuming SearchMe is the example directory name you need to traverse completely.
I am also assuming, since it was not specified, the files you want to modify are all text file. Is this correct?
In such scenario I would suggest using the command:
find SearchMe -type f -exec vi {} \;
If you are not familiar with vi editor, just use another one (nano, emacs, kate, kwrite, gedit, etc.) and it should work as well.
Bash 4+
shopt -s globstar
for file in **
do
if [ -f "$file" ];then
# do some processing to your file here
# where the find command can't do conveniently
fi
done

Bash script to recursively step through folders and delete files

Can anyone give me a bash script or one line command i can run on linux to recursively go through each folder from the current folder and delete all files or directories starting with '._'?
Change directory to the root directory you want (or change . to the directory) and execute:
find . -name "._*" -print0 | xargs -0 rm -rf
xargs allows you to pass several parameters to a single command, so it will be faster than using the find -exec syntax. Also, you can run this once without the | to view the files it will delete, make sure it is safe.
find . -name '._*' -exec rm -Rf {} \;
I've had a similar problem a while ago (I assume you are trying to clean up a drive that was connected to a Mac which saves a lot of these files), so I wrote a simple python script which deletes these and other useless files; maybe it will be useful to you:
http://github.com/houbysoft/short/blob/master/tidy
find /path -name "._*" -exec rm -fr "{}" +;
Instead of deleting the AppleDouble files, you could merge them with the corresponding files. You can use dot_clean.
dot_clean -- Merge ._* files with corresponding native files.
For each dir, dot_clean recursively merges all ._* files with their corresponding native files according to the rules specified with the given arguments. By default, if there is an attribute on the native file that is also present in the ._ file, the most recent attribute will be used.
If no operands are given, a usage message is output. If more than one directory is given, directories are merged in the order in which they are specified.
Because dot_clean works recursively by default, use:
dot_clean <directory>
If you want to turn off the recursively merge, use -f for flat merge.
dot_clean -f <directory>
find . -name '.*' -delete
A bit shorter and perform better in case of extremely long list of files.

How does one find and copy files of the same extension, in different directories, to a single directory in linux?

So, How Do I find and copy all files,
*.a
that are in,
~/DIR{1,2,3,...}
to
~/tmp/foo?
Assumed you meant recursively copy everything of type .a from some source location.
Haven't verified yet, but this should do that.
find <root-of-search> -type f -name '*.a' -exec cp {} /tmp/foo \;
replace with the top of wherever you want to search from. You might have to throw quotes around *.a, and you might have to replace escape the ending semicolon by putting it in single quotes rather than back-slashing it.
In a bash shell:
cp ~/DIR*/*.a ~/tmp/foo
find ~/DIR{1,2,...} -name *.a print0 | xargs -i -0 cp '{}' ~/tmp/foo

Resources