I want to use the find command to execute a special command on all of the files inside the directory that are contained inside multiple different directories with a specific keyword in it (the keyword is "Alpha") and keep the output inside the working directory of the initial file I ran the command on.
The command works such that it requires to you to provide the initial file to perform the command on and then the name of the newly converted file. So like this
command file_to_run_command_on.txt new_file.txt
This is my code
find $PWD -name *.txt* -exec command {} new_file. \;
Right now, it finds all the text files in this directory even in the sub directories and outputs just one file in the directory I run the initial find command from. I'm also unsure how to add the additional search for the keyword in the directory. All advice appreciated!
-exec runs the command in the directory from which you start find.
-execdir runs the command in the matching file's directory.
To only find *.txt* files whose parents contain a specific file, you could use:
find "$PWD" -path "*keyword*/*.txt*" -execdir command {} new_file \;
This will run the command for foo/bar/some-keyword-dir/baz/etc/file.txts but not for foo/bar/baz/file.txts (no keyword in parent directory names) or foo/bar/some-keyword-dir/baz/file.tar (not *.txt*)
I have a bash script that successfully deletes catalina.out files for one or more tomcat log directories (we run multiple instances) once the file exceeds a certain size. I run this script nightly as a cron job. It essentially looks like this:
find /apache-tomcat-blah*/. -name catalina.out -size +1000M -delete
However, my problem is I need to automatically create a new empty one in its place as soon as the old one is deleted.
The challenge is I will not know ahead of time which catalina.out from which tomcat instance was deleted. Also, I do not want to assume I know all the tomcat instances corresponding to /apache-tomcat-blah*/. We change them from time to time.
I assume the find command knows what it just deleted (maybe I should not assume that) so that I could theoretically pipe that information as in:
$ echo "" > /apache-tomcat-justDeletedFromDir/logs/catalina.out
if I could figure out what to put in the apache-tomcat-justDeletedFromDir part of the string.
I would be grateful for any ideas. Thank you!
Why not just use something like:
for f in $(find /apache-tomcat-blah*/. -name catalina.out -size +1000M); do
rm $f
touch $f
done
so your find command is now executed in a subshell $(), and your bash script iterates through the output (the list of files) and removes each one (via rm) and creates a new one (via touch)
You would need to be careful with the above if your files have spaces in them (note).
The code I have at the moment is:
#!/bin/bash
cd "/Users/{User}/Documents/jarfiles/"
runnable_game=$(find . -type f -name 'game\..*\.jar')
echo $runnable_game
eval $runnable_game
in my Documents folder I have a folder jarfiles and within that folder there is only 1 jar file, although if possible only make it select the first file found.
The goal is to execute this file. for example: /Documents/jarfiles/game.1234.jar should be run.
for debug I put an echo in there, but the echo returned nothing, a blank line.
I have some programming skill, but I am not professional and in no way used to shell scripts or terminal command line magic. (I program in Java, C and such...)
Any idea to make a script that finds a file and runs it?
to clarify:
I don't know the filename in advance any .jar file to that format should be run, basically I download a file to that directory which is in that format
To execute a jar file you know is there but you don't know the exact name,
you can use a simple shell wildcard,
you don't need the find command:
java -jar game*.jar
If you want to execute only the first file found, then find can be indeed useful:
find . -name 'game*.jar' -exec java -jar {} \; -quit
Correct shell code to run 'game' + any string + 'jar'
#!/bin/bash
cd "/Users/{User}/Documents/jarfiles"
java -jar $(find . -name 'game.*jar')
game\..*\.jar escaping using \ seemed to not work
this will find files starting with game and ending with jar, not game. and .jar, which is not a problem (at the moment).
I have a directory with about 5,000 subdirectories in it.
Each subdirectory contains one file each.
I'd like to collect those files and put them in the same folder somewhere.
Is there a way to do that by Mac OSX terminal command? Or should I write a, say, python script to do that?
Something like,
find . -type f -exec echo mv {} /path/to/dst/dir/ \;
You'll have to tweak this according to your circumstances, of course. See man find for details. Remove the echo when you're ready to run for real (preferably after taking a backup).
In editors/ides such as eclipse and textmate, there are shortcuts to quickly find a particular file in a project directory.
Is there a similar tool to do full path completion on filenames within a directory (recursively), in bash or other shell?
I have projects with alot of directories, and deep ones at that (sigh, java).
Hitting tab in the shell only cycles thru files in the immediate directory, thats not enough =/
find /root/directory/to/search -name 'filename.*'
# Directory is optional (defaults to cwd)
Standard UNIX globbing is supported. See man find for more information.
If you're using Vim, you can use:
:e **/filename.cpp
Or :tabn or any Vim command which accepts a filename.
If you're looking to do something with a list of files, you can use find combined with the bash $() construct (better than backticks since it's allowed to nest).
for example, say you're at the top level of your project directory and you want a list of all C files starting with "btree". The command:
find . -type f -name 'btree*.c'
will return a list of them. But this doesn't really help with doing something with them.
So, let's further assume you want to search all those file for the string "ERROR" or edit them all. You can execute one of:
grep ERROR $(find . -type f -name 'btree*.c')
vi $(find . -type f -name 'btree*.c')
to do this.
When I was in the UNIX world (using tcsh (sigh...)), I used to have all sorts of "find" aliases/scripts setup for searching for files. I think the default "find" syntax is a little clunky, so I used to have aliases/scripts to pipe "find . -print" into grep, which allows you to use regular expressions for searching:
# finds all .java files starting in current directory
find . -print | grep '\.java'
#finds all .java files whose name contains "Message"
find . -print | grep '.*Message.*\.java'
Of course, the above examples can be done with plain-old find, but if you have a more specific search, grep can help quite a bit. This works pretty well, unless "find . -print" has too many directories to recurse through... then it gets pretty slow. (for example, you wouldn't want to do this starting in root "/")
I use ls -R, piped to grep like this:
$ ls -R | grep -i "pattern"
where -R means recursively list all the files, and -i means case-insensitive. Finally, the patter could be something like this: "std*.h" or "^io" (anything that starts with "io" in the file name)
I use this script to quickly find files across directories in a project. I have found it works great and takes advantage of Vim's autocomplete by opening up and closing an new buffer for the search. It also smartly completes as much as possible for you so you can usually just type a character or two and open the file across any directory in your project. I started using it specifically because of a Java project and it has saved me a lot of time. You just build the cache once when you start your editing session by typing :FC (directory names). You can also just use . to get the current directory and all subdirectories. After that you just type :FF (or FS to open up a new split) and it will open up a new buffer to select the file you want. After you select the file the temp buffer closes and you are inside the requested file and can start editing. In addition, here is another link on Stack Overflow that may help.
http://content.hccfl.edu/pollock/Unix/FindCmd.htm
The linux/unix "find" command.
Yes, bash has filename completion mechanisms. I don't use them myself (too lazy to learn, and I don't find it necessary often enough to make it urgent), but the basic mechanism is to type the first few characters, and then a tab; this will extend the name as far as it can (perhaps not at all) as long as the name is unambiguous. There are a boatload of Emacs-style commands related to completion in the good ol' man page.
locate <file_pattern>
*** find will certainly work, and can target specific directories. However, this command is slower than the locate command. On a Linux OS, each morning a database is constructed that contains a list of all directory and files, and the locate command efficiently searches this database, so if you want to do a search for files that weren't created today, this would be the fastest way to accomplish such a task.