Using find command but getting the error "paths must precede expression" - unix

I'm trying to use the find command, but get "paths must exceed expression:name"
I've looked at the answers given here previously and added quotes around my expression, but it still is giving me the same error. My $SUB path is /home/year/sessions/subjects/MRI
find $SUB \( -name '*first*.tgz' -o name '*second*.tgz' \) -exec cp {} ./$SUBJECT1 \;
Is my path-to-file incorrect? Thanks in advance

The correct command is:
find $SUB \( -name '*first*.tgz' -o -name '*second*.tgz' \) -exec cp {} ./$SUBJECT1 \;

Related

BASH: performing a regex replace on a path from find command

AIM: to find all JS|TS excluding *.spec.js files in a directory but replace the base path with ./
I have this command
find src/app/directives -name '*.[j|t]s' ! -name '*.spec.js' -exec printf "import \"%s\";\n" {} \;
which in said directory prints the marked JS files. However I want to replace the src/app with ./
I've tried playing with [[]] and this command but they don't work.
find src/app/components -name '*.[j|t]s' ! -name '*.spec.js' -exec printf "import \"%s\";\n" ${{}/src
/hi} \;
zsh: bad substitution
Given your "AIM", all you really need is:
find src/app/directives -type f -name "*.[jt]s" ! -name "*.spec.js" -printf "./%f\n"
The reason being is the '|' in your character-class isn't matching anything, but isn't hurting anything for that matter. Your second ! -name "*.spec.js" is fine. You don't need -exec and can simply use -printf "./%f\n" (where "%f" provides the filename only for the current file). You simply prepend the "./" as part of the -printf format-string.
Let me know if I misunderstood your AIM or if you have further questions.
Removing src/app/directives While Preserving Remaining Path
If you want to preserve the remainder of the path after src/app/directives (essentially just replacing it with '.'), you can use a short helper-script with the POSIX parameter expansion to trim src/app/directives from the front of the string replacing it with '.' using printf in the helper script. For example the helper could be:
#!/bin/zsh
printf ".%s" "${1#./src/app/directives}"
(note: the leading "./" being removed along with src/app/directives is prepended by find, the '.' added by the printf format-string will result in the returned filename being ./rest/of/path/to/filename)
Call the script whatever you like, helper.sh below. Make it executable chmod +x helper.sh.
The find call would then be:
find src/app/directives -type f -name "*.[jt]s" ! -name "*.spec.js" -exec path/to/helper.sh '{}' \;
Give that a go and let me know if it does what you are needing.

How to use find exec cp with a regex pattern?

I want to copy some files with string "ABC" in their name and without string "DEF" in their name using the find -exec command. This post mentions how to do it for the without case using find command. I want to know how to do it for both with and without cases.
You can use -and or -a for multiple true condition as follows. ! for negation can be applied after and
find . \( -regex ".*ABC.*" -and ! -regex ".*DEF.*" \) -exec cp {} /destination/folder/ \;

Unix to find exact match of string

I'm looking to find a way to match an exact string
for example:
I have these cmd that I run on unix server
1.)find ./ -name "*.jsp" -type f -exec grep -m1 -l '50.000' {} + >> 50dotcol.txt
2.)find ./ -name ".jsp" -type f -exec grep -m1 -l '\<50.000>' {} + >> 50dotcol.txt
Edited after Georges response:
find ./ -name "*.jsp" -type f -exec grep -m1 -l '(50.000)' {} + >> 50dotcol.txt
Still didn't pull in any results
The first one will find any string containing "50" the second will omit double digit strings but will pull in $50,000 $50.000. But I'm just looking to pull in "50.000" and that's it, no other variations of this
Am I missing something in my find cmd?
Use
grep -m1 -l '(50\.000)'
instead. That backslash before the < interprets it literally, which you don't want to do. And you need to use parenthesis to have it considered as an exact group of characters.

grep on some files

I want to find all files with extension x in all sub folders containing string s, how do I do this?
grep -nr s .*.x ?????
Dirk
GNU find
find . -iname "*.x" -type f -exec grep -l "s" {} +;
If you have Ruby(1.9+)
Dir["/path/**/*.x"].each do |file|
if test(?f,file)
open(file).each do |line|
if line[/s/]
puts "file: #{file}"
break
end
end
end
end
I would first find the *.x files, and then search the string you are interested in with grep:
$ find directory -name "*.x" -exec grep -Hn s {} \;
-name "*.x" searches recursively every file sufixed with x.
-exec grep ... {} \; searchs the s string for each encountered file.
-H is recommended, since you wouldn't know which file matched the expression.

Unix Find Replace Special Characters in Multiple Files

I've got a set of files in a web root that all contain special characters that I'd like to remove (Â,€,â,etc).
My command
find . -type f -name '*.*' -exec grep -il "Â" {} \;
finds & lists out the files just fine, but my command
find . -type f -name '*.*' -exec tr -d 'Â' '' \;
doesn't produce the results I'm looking for.
Any thoughts?
to replace all non-ascii characters in all files inside the current directory you could use:
find . -type f | xargs perl -pi.bak -e 's,[^[:ascii:]],,g'
afterwards you will have to find and remove all the '.bak' files:
find . -type f -a -name \*.bak | xargs rm
I would recommend looking into sed. It can be used to replace the contents of the file.
So you could use the command:
find . -type f -name '*.*' -exec sed -i "s/Â//" {} \;
I have tested this with a simple example and it seems to work. The -exec should handle files with whitespace in their name, but there may be other vulnerabilities I'm not aware of.
Use
tr -d 'Â'
What does the ' ' stands for? On my system using your command produces this error:
tr: extra operand `'
Only one string may be given when deleting without squeezing repeats.
Try `tr --help' for more information.
sed 's/ø//' file.txt
That should do the trick for replacing a special char with an empty string.
find . -name "*.*" -exec sed 's/ø//' {} \
It would be helpful to know what "doesn't produce the results I'm looking for" means. However, in your command tr is not provided with the filenames to process. You could change it to this:
find . -type f -name '*.*' -exec tr -d 'Â' {} \;
Which is going to output everything to stdout. You probably want to modify the files instead. You can use Grundlefleck's answer, but one of the issues alluded to in that answer is if there are large numbers of files. You can do this:
find . -type f -name '*.*' -print0 | xargs -0 -I{} sed -i "s/Â//" \{\}
which should handle files with spaces in their names as well as large numbers of files.
with bash shell
for file in *.*
do
case "$file" in
*[^[:ascii:]]* )
mv "$file" "${file//[^[:ascii:]]/}"
;;
esac
done
I would use something like this.
for file in `find . -type f`
do
# Search for char end remove it. Save file as file.new
sed -e 's/[ۉ]//g' $file > $file.new
# mv file.new to file DON'T RUN IF YOU WILL NOT OVERITE ORIGINAL FILE
mv $file.new $file
done
The above script will fail as levislevis85 has mentioned it with spaces in filenames. This would not be the case if you use the following code.
find . -type f | while read file
do
# Search for char end remove it. Save file as file.new
sed -e 's/[ۉ]//g' "$file" > "$file".new
# mv file.new to file DON'T RUN IF YOU WILL NOT OVERITE ORIGINAL FILE
mv "$file".new "$file"
done

Resources