How to use ag aka the_silver_search to search for directories only? - ag

I like to search for directories only, and the option ag --list-file-types is not helpful with that. The reason to stick to ag is the possibility to pick a file with --path-to-ignore containing patterns to ignore.
An equivalent command would be fd --type d.

Use the -G argument, and specify a directory name.
For example, if you wanted to search for the word "foobar" in only your Downloads directory:
ag -G "Downloads/" foobar

Related

list all files in directory and subdirectories in linux with specific pattern filename

i have some lot of files inside of directories and subdirectories like this :
108400344_2223_bab4.pdf
and
15.04.1150_bab4.pdf
I want to list and count all files which have a pattern like second one.
I'm using this command
ls -LR | grep bab4.pdf
but the command show all files including files which have a pattern with a name like the first one.
Any idea?
thanks
You can take advantage of the fact that there is only one underscore:
ls -LR | grep '^[^_]*_bab4.pdf'

How can I force ag to find matches in node_modules?

I'm using ag to search a git repo. It doesn't find matches under my node_modules subdirectory. Why not, and how can I control this behavior?
It turns out that ag honors the contents of the .gitignore file by default. So if node_modules is in .gitignore, ag won't search it. This is all sensible behavior, but difficult to debug if you aren't expecting it. Hopefully this post will help.
There's a good summary at the end of man ag:
IGNORING FILES
By default, ag will ignore files whose names match patterns in .gitig-
nore, .hgignore, or .agignore. These files can be anywhere in the
directories being searched. Ag also ignores files matched by the
svn:ignore property if svn --version is 1.6 or older. Finally, ag looks
in $HOME/.agignore for ignore patterns. Binary files are ignored by
default as well.
If you want to ignore .gitignore, .hgignore, and svn:ignore, but still
take .agignore into account, use -U.
Use the -t option to search all text files; -a to search all files; and
-u to search all, including hidden files.
For my purposes ag -t seems to work well.

Use [msys] bash to remove all files whose name matches a pattern, regardless of file-name letter-case

I need a way to clean up a directory, which is populated with C/C++ built-files (.o, .a, .EXE, .OBJ, .LIB, etc.) produced by (1) some tools which always create files having UPPER-CASE names, and (2) other tools which always create lower-case file names. (I have no control over the tools.)
I need to do this from a MinGW 'msys' bash.exe shell script (or bash command prompt). I understand piping (|), but haven't come up with the right combination of exec's yet. I have successfully filtered the file names, using commands like this example:
ls | grep '.\.[eE][xX][eE]'
to list all files having any case-combination of letters in the file-extension--this example gets all the executable (e.g. ".EXE") files.
(I'll be doing similar for .o, .a, .OBJ, .LIB, .lib, .MAP, etc., which all share the same directory as the C/C++ source files. I don't want to delete the source files, only the built-files. And yes, I probably should rework the directory structure, to use a separate directory for the built-files [only], but that will take time, and I need a quick solution now.)
How can I merge the above command with "something" else (e.g., like the 'rm -f' command???), to carry this the one step further, to actually delete [only] those filtered-out files from the current directory? (I'm hopeful for a solution which does not require a temporary file to hold the filtered file names.)
Adding this answer because the accepted answer is suggesting practices which are not-recommended in actual scripts. (Please don't feel bad, I was also on that track once..)
Parsing ls output is a NO-NO! See http://mywiki.wooledge.org/ParsingLs for more detailed explanation on why.
In short, ls separates the filenames with newline; which can be present in the filename itself. (Plus, ls does not handle other special characters properly. ls prints the output in human readable form.) In unix/linux, it's perfectly valid to have a newline in the filename.
A unix filename cannot have a NULL character though. Hence below command should work.
find /path/to/some/directory -iname '*.exe' -print0 | xargs -0 rm -f
find: is a tool used to, well, find files matching the required pattern/criterion.
-iname: search using particular names, case insensitive. Note that the argument to -iname is wildcard, not regex.
-print0: Print the file names separated by NULL character.
xargs: Takes the input from stdin & runs the commands supplied (rm -f in this case) on them. The input is separaed by white-space by default.
-0 specifies that the input is separated by null character.
Or even better approach,
find /path/to/some/directory -iname '*.exe' -delete
-delete is a built-in feature of find, which deletes the files found with the pattern.
Note that if you want to do some other operation, like move them to particular directory, you'd need to use first option with xargs.
Finally, this command find /path/to/some/directory -iname '*.exe' -delete would recursively find the *.exe files/directories. You can restrict the search to current directory with -maxdepth 1 & filetype to simple file (not directory, pipe etc.) using -type f. Check the manual link I provided for more details.
this is what you mean?
rm -f `ls | grep '.\.[eE][xX][eE]'`
but usually your "ls | grep ..." output will have some other fields that you have to strip out such as date etc., so you might just want to output the file name itself.
try something like:
rm -f `ls | grep '.\.[eE][xX][eE]' | awk '{print $9}'`
where you file name is in the 9th field like:
-rwxr-xr-x 1 Administrators None 283 Jul 2 2014 search.exe
You can use following command:
ls | grep '.\.[eE][xX][eE]' | xargs rm -f
Use of "xargs" would turn standard input ( in this case output of the previous command) as arguments for "rm -f" command.

How do I add a persistent configuration option to 'ag'?

I have recently begun to use the 'ag' command instead of 'ack'.
Ag is much faster, but does not seem to have a file (such as .ackrc) where one could add configuration options.
For example, I always want a pager to be used, and I don't want to have to always type in:
ag --pager "less -R"
How about putting the following in your command line configuration file (such as .bashrc or .zshrc)?
alias ag="ag $* --pager 'less -R'"
Hope this is not way too late.
Run man ag on linux box. Right at the end if the following text:
By default, ag will ignore files matched by patterns in .gitignore,
.hgignore, or .agignore. These files can be anywhere in the
directories being searched. Ag also ignores files matched by the
svn:ignore property in sub‐
version repositories. Finally, ag looks in $HOME/.agignore for ignore patterns. Binary files are ignored by default as well.
Note the part I emphasised. So just add .agignore file and ignore patterns in there
-

ack: Exclude specific directories from search via regex

How do I ignore specific directories via RegEx with ack?
I can use the --ignore-dir option, but this does not let me specify a RegEx. I want to be able to ignore any directory, which has the words test or tests or more complicated patterns in its name.
I also tried a negative lookbehind via
ack -G '(?<!test)' pattern
but this does not work. It does not exclude the test directories.
Use the undocumented option "--invert-file-match" (ack version on my system: 1.96):
$ ack pattern -G 'test|tests' --invert-file-match
Well, it is sort of documented:
$ ack --help|grep invert
-v, --invert-match Invert match: select non-matching lines
--invert-file-match Print/search handle files that do not match -g/-G.
It is not documented in its perldoc.
With ack2, it seems you can't use holygeek's solution.
Here's how I'd do it using -v and -x:
ack -v -g 'test' | ack -x pattern
More generally, 'test' can be a regex for dirs to exclude
In recent versions of ack, you can use regular expressions with --ignore-dir.
From this thread:
Yes, in 2.15_01 we added:
ack now supports --ignore-dir=match:.... Thanks, Ailin Nemui! (GitHub ticket #42)
GitHub link: https://github.com/petdance/ack2/issues/42
Sadly, I think this only supports matching the base directory name, not the full path.
For instance, you cannot match a path like ".*/docs/generated/.*" with it.
For that, see the GitHub issue 291.
update for 2020: it looks like this is now moved to ack3 (github issue).
In the interest of folks using a pre-1.96 version of ack (like me), you can use regex look around to do this. Here's an example:
ack --java 'text-pattern' -G '^((?!(test|target)).)*$'
This will search the text-pattern in all Java files recursively (from .) that DO NOT have the words test or target in their path.