Why do I need '-o' in linux find command? [closed] - linux

Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 months ago.
Improve this question
I want to list files with certain name pattern under certain directory, and excluding certain sub-directory.
By doing
find "../../" -path "../../backup" -prune -regex "\.*\.v" -print
nothing is outputted.
But by adding -o
find "../../" -path "../../backup" -prune -o -regex "\.*\.v" -print
I get the correct results.
-o means or. But I don't think there is an or logic in my requirements, I think it should be and?
file name with certain pattern & under certain directory & not under certain sub-directory
Am I doing something wrong?

From the find man page:
-prune True; if the file is a directory, do not descend into it.
If -depth is given, false; no effect.
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
The construct -prune -o \( ... -print0 \) is quite common.
The idea here is that the expression before -prune matches
things which are to be pruned.
However, the -prune action itself returns true, so the following
-o ensures that the right hand side is evaluated only for
those directories which didn't get pruned (the contents of
the pruned directories are not even visited, so their contents are irrelevant).

Related

Filter and copy all the subdirectories and its content [closed]

Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 15 days ago.
Improve this question
I have a list of directories and files that I need to migrate. The directory tree looks something like:
-var
-data
-archive
-111111
-logs
datetime.log
meter.txt
-222222
-logs
datetime.log
meter.txt
-configurations
-rules
config.json
-recycle
When copying, it should satisfy the below conditions:
Copy only files/ directories that are less than or equal to 30 days. (This condition is not applicable to the configurations directory. Get all contents under configuration irrespective of its creation/modification date time.)
Exclude the directory recycle.
Copy only the content under archive. That means do not copy directories var, data & archive.
After copying the directory should look something like this:
-target
-111111
-logs
datetime.log
meter.txt
-222222
-logs
datetime.log
meter.txt
-configurations
-rules
config.json
I came up with this:
find var/data/archive ! -path "*/recycle*" \( -path "*/configurations*" -o -name "*" -mtime -30 \) | rsync -av --inplace --files-from=- . target
I am able to achieve the first 2 conditions, i.e. copying files that are less than 30 days and excluding the directory recycle. But not able to exclude var/data/archive. How do I fix this?
This worked for me.
cd ${HOME}/var/data/archive;\
find . ! -path "*/recycle*" \( -path "*/configurations*" -o -name "*" -mtime -10 \) | rsync -av --inplace --files-from=- . ${HOME}/target

Linux shell select files in directory and subdirectiry [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
Improve this question
For selecting all php files in a folder , we use :
vim *.php
How to use this command for selecting *.php files in this directory and his subdirectories ?
With shell option `globstar`` in bash you can use
vim **/*.php
To enable the shell option use e.g.
shopt -s globstar
You can use find combined with xargs:
find . -type f -name '*.php' -print0 | xargs -0 vi
The find will locate all regular files matching *.php, in and below the current directory, and send all the names in a stream to xargs separated by NUL characters.
The xargs program (with a -0 matching the -print0) will then separate them into individual file names and pass as many as possible to a single vi invocation. If it can't fit them all in one invocation (unlikely, unless the number of files is truly massive), it will make multiple invocations as needed.
You could use brace expansions:
vim {,*/}*.php
How does it work
{,*/} expands to <empty> dir1/ dir2/ ...
the final command line is then: ls *.php dir1/*.php dir2/*.php ...
This only matches immediate subdirectories, so subdirectories of a subdirectory won't be included. As mentioned in the other answeres, find or globstar is better suited for that.

Use find command with -perm and -maxdepth [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
When I Enter this command:
$ find . -perm 777 -maxdepth 1
The following error occures:
find: warning: you have specified the -maxdepth option after a non-option argument -perm, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.
What does that mean?
The order of find arguments is very important, because they are evaluated as a boolean expression left-to-right with short circuiting:
# Deletes *.tmp files
find . -name '*.tmp' -delete
# Deletes ALL file, because -delete is performed before -name
find . -delete -name '*.tmp'
However, -maxdepth does not behave like this. -maxdepth is an option that changes how find works, so it applies the same no matter where it's placed:
# Deletes all '*.tmp' files, but only in the current dir, not subdirs
find . -maxdepth 1 -name '*.tmp' -delete
# Deletes all '*.tmp' files, still only in the current dir
find . -name '*.tmp' -delete -maxdepth 1
Since you put the -maxdepth 1 after a -perm 777, it looks like you are trying to make -maxdepth only apply to certain files. Since this is not possible, find prints this warning.
It suggests that you rewrite it into find . -maxdepth 1 -perm 777 to make it clear that you intended -maxdepth to apply to everything.

Rich globbing `ls [G-S]*` in fish shell? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 5 years ago.
Improve this question
In Bash it is possible to
ls [G-S]*
and it would list all files from g-s and G-S.
How is that done in Fish shell?
Fish currently does not support a rich glob syntax. The current thinking is that a glob command should be added in keeping with the fish goal of doing things via commands rather than magic syntax. See, for example, https://github.com/fish-shell/fish-shell/issues/3681. The solution is to create a function that filters the results. For example, the ** glob matches all files and directories in and below the CWD. I frequently want just the plain files and want to ignore the .git subdir. So I wrote this function:
function ff --description 'Like ** but only returns plain files.'
# This also ignores .git directories.
find . \( -name .git -type d -prune \) -o -type f | sed -n -e '/\/\.git$/n' -e 's/^\.\///p'
end
Which I can then use like this: grep something (ff). You could create a similar function that uses the find -name pattern matching feature or filter the results with string match --regex.
You can use find -iregex "./[G-S].*". Fish is quite limited in this regard.

find -mtime returns wrong listing [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
When I run this command:
root:/home/mws 0$ ls -lrt `find /home/data/ll_misc_logs/ -mtime +20`
And there are no files meeting the mtime setting, 20 days, it lists the contents of the current directory, /home/mws
Why?
Is there a way to just return nothing or a message?
When there are no files meeting the mtime setting, the output of find .... expands to ... nothing. In which case, your command becomes ls -lrt, which will always list the current directory.
If there aren't too many files on a typical run, this might work better:
find /home/data/ll_misc_logs -mtime +20 -print0 | xargs -0 -r ls -ltr
But, if you get so many files that xargs decides to split it into multiple invocations, it probably won't do exactly what you want, either.
Which leads me to... What exactly are you trying to do? On the surface, it looks like "show me the old files, in order by modification time", but it's likely part of something bigger that might be solved in a more efficient (and less error-prone) manner...
If you just want a list of files older than 20 days sorted by oldest first:
find /home/data/ll_misc_logs -mtime +20 -exec ls -l --time-style=%s {} \; | sort -n -k 6

Resources