How to find and move from the current directory in bash - bash

I'm trying to move a script from the directory I'm in to another directory after I have performed a find in the current directory. Although I don't get an error nothing happens. I don't know why. Can you help?
find . -name ScriptsFlowchart.xml -execdir mv {} Users/me/Desktop/SequencingScripts/{} \;

Try using -exec instead of -execdir and drop {} in target definition.
find . -name ScriptsFlowchart.xml -exec mv {} Users/me/Desktop/SequencingScripts/ \;
{} will retrieve the file path relative to current dir. So you must run the mv command from the current dir as well (using -exec).
From find manual page:
-execdir command ;
Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find.
If that's in a bash script, try reading $? right after running the command to check if there were any errors (if equals 0, runs successfully).

Related

Using fish shell builtins with find exec

I'm trying to source a file that I can get from the output of find using these commands:
find ./ -iname activate.fish -exec source {} \;
and
find ./ -iname activate.fish -exec builtin source {} \;
But both these commands give the error of the form find: ‘source’: No such file or directory or find: ‘builtin’: No such file or directory. Seems like exec of find is not able to recognize fish's builtins ?
What I basically want to achieve is a single command that will search for Python's virtualenv activate scripts in the current directory and execute them.
So doing something like -exec fish -c 'source {}; \ would not help. I've tried it as well and it doesn't error out but does not make the changes either.
Any ideas what can be done for this ?
Thanks!
Perhaps you need:
for file in (find ./ -iname activate.fish)
source $file
end
# or
find ./ -iname activate.fish | while read file
source $file
end
Command substitution executes the command, splits on newlines, and returns that list.
As mentioned in comments, seems like -exec does not run in or affect the current shell environment. So find -exec is not gonna work for my use case.
Instead, this will work:
source (find ./ -iname activate.fish)

What is good way to move a directory and then run a command to the file inside it using a bash shell one-liner

I would like to find txt files with find command and move the directory of the found file, and then apply a command to the file using a bash shell one-liner
For example, this command works, but the acmd is executed in the current directory.
$ find . -name "*.txt" | xargs acmd
I would like to run acmd in the txt file's direcotry.
Does anyone have good idea?
From the find man page:--
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirec‐
tory containing the matched file, which is not normally the
directory in which you started find. This a much more secure
method for invoking commands, as it avoids race conditions dur‐
ing resolution of the paths to the matched files. As with the
-exec action, the `+' form of -execdir will build a command line
to process more than one matched file, but any given invocation
of command will only list files that exist in the same subdirec‐
tory. If you use this option, you must ensure that your $PATH
environment variable does not reference `.'; otherwise, an
attacker can run any commands they like by leaving an appropri‐
ately-named file in a directory in which you will run -execdir.
The same applies to having entries in $PATH which are empty or
which are not absolute directory names. If find encounters an
error, this can sometimes cause an immediate exit, so some pend‐
ing commands may not be run at all. The result of the action
depends on whether the + or the ; variant is being used;
-execdir command {} + always returns true, while -execdir com‐
mand {} ; returns true only if command returns 0.
Just for completeness, the other option would be to do:
$ find . -name \*.txt | xargs -i sh -c 'echo "for file $(basename {}), the directory is $(dirname '{}')"'
for file schedutil.txt, the directory is ./Documentation/scheduler
for file devices.txt, the directory is ./Documentation/admin-guide
for file kernel-parameters.txt, the directory is ./Documentation/admin-guide
for file gdbmacros.txt, the directory is ./Documentation/admin-guide/kdump
...
i.e. have xargs "defer to a shell". In usecases where -execdir suffices, go for it.

Run a bash script within Automator using positional parameters

This is my first time using Automator and it seems like a pretty nifty tool. I am running into an issue however at the very end of the automation. The goal of my automator workflow is to specify a path, then create a directory Highschool1, for example, within that path.
From here, I want it to search for any files within the specified path that include "Highschool1" in the name, and move them into the new Highschool1 directory. Here is how my bash script works within terminal:
mkdir "/Users/tommy/Desktop/TestShow1/WG/Highschool1"
This creates the directory as intended. Then:
find /Users/tommy/Desktop/TestShow1/WG -name 'Highschool1' -prune -o -type f -name '*Highschool1*' -exec mv -- {} /Users/tommy/Desktop/TestShow1/WG/Highschool1 \;
This finds the files I want while excluding the new Highschool1 directory, and then moves the found files into that Highschool1 directory. It is all working as intended at the base.
It's when I try to apply this script within my automation using positional parameters that it stops working.
-I stuff a variable called "HighschoolName" with the input "Highschool1"
-Then I stuff a variable called "pathA" with the input, which is the path I chose: "/Users/tommy/Desktop/TestShow1/WG"
-Then I call back my HighschoolName variable and begin with the positional parameters.
This is the final script I used:
mkdir "$1/$2"
find /$1 -name '$2' -prune -o -type f -name '*$2*' -exec mv -- {} /$1/$2 \;
This creates the directory Highschool1 where I want it, but fails to move any files into it. It gives me no error message either. It simply acts as if the script was run successfully. Does anyone have any idea what the problem could be?
Read about quoting
In:
find /$1 -name '$2' -prune -o -type f -name '*$2*' -exec mv -- {} /$1/$2 \;
'$2' will not interpolate the variables, you need to use "$2" (same for '*$2*')

How to run my bash script from any folder

I am trying to run my bash script from another folder
I want it to be executed from which folder i want
What should I do ?
Im trying to used find in the beginning but it doesnt work !
find /path/to/Files -type d -exec Notes-Khaled-Mustafa.sh {} \;
./Notes-Khaled-Mustafa.sh {} simply path the current folder as a parameter to your script.
Which is not what you want. You want to execute your script with, as its current execution folder, the one you list through the find command.
That is done by calling a subshell and executing a cd in it.
In your bash session, try instead:
find . -type d -execdir /path/to/Note-khaled-mustafa.sh \;
So not "./Note-khaled-mustafa.sh", but "/absolute/full/path/to/Note-khaled-mustafa.sh"
This uses -execdir to change directory to each matched path. If your version of find doesn't have -execdir, use instead:
find . -type d -exec sh -c 'cd "$1" && /path/to/Note-khaled-mustafa.sh' sh {} \;
If you really just want to run the script and you do know the name, try
/path/to/Notes-Khaled-Mustafa.sh
if this does not work, change the permissions:
chmod +x /path/to/Notes-Khaled-Mustafa.sh
/path/to/Notes-Khaled-Mustafa.sh

Find files, rename in place unix bash

This should be relatively trivial but I have been trying for some time without much luck.
I have a directory, with many sub-directories, each with their own structure and files.
I am looking to find all .java files within any directory under the working directory, and rename them to a particular name.
For example, I would like to name all of the java files test.java.
If the directory structure is a follows:
./files/abc/src/abc.java
./files/eee/src/foo.java
./files/roo/src/jam.java
I want to simply rename to:
./files/abc/src/test.java
./files/eee/src/test.java
./files/roo/src/test.java
Part of my problem is that the paths may have spaces in them.
I don't need to worry about renaming classes or anything inside the files, just the file names in place.
If there is more than one .java file in a directory, I don't mind if it is overwritten, or a prompt is given, to choose what to do (either is OK, it is unlikely that there are more than one in each directory.
What I have tried:
I have looked into mv and find; but, when I pipe them together, I seem to be doing it wrong. I want to make sure to keep the files in their current location and rename, and not move.
The GNU version of find has an -execdir action which changes directory to wherever the file is.
find . -name '*.java' -execdir mv {} test.java \;
If your version of find doesn't support -execdir then you can get the job done with:
find . -name '*.java' -exec bash -c 'mv "$1" "${1%/*}"/test.java' -- {} \;
If your find command (like mine) doesn't support -execdir, try the following:
find . -name "*.java" -exec bash -c 'mv "{}" "$(dirname "{}")"/test.java' \;

Resources