How can I tell ack to search in two distinct directories? - grep

Is it possible to ask ack to search and include results from multiple root directories, rather than searching from the current shell working directory?

Yes, you can specify any number of files or directories you want to search.
Look at the first line of ack --help.
Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES]
(The ack manpage has a similar usage statement)
So you can do
ack needle this_haystack/ that/haystack/ other/haystack*.txt

Related

How to grep for files using 'and' operator, words might not be on the same line

I have a directory /dir
which has several text files in it, These files may or may not contain the words 'rock' and 'stone', so basically some files might just contain the word 'rock', some may just contain the word 'stone', some may contain both, and some may contain neither.
How can I list all files in this directory that contain both 'rock' and 'stone'? These words might not be on the same line so I don't think piping through grep twice would work.
Appreciate any help, I was not able to find a stackoverflow post with this problem so I figured I'd ask.
To search files that match the given two (or more) words at any line anywhere in the file, you may want to try ugrep:
ugrep -F --files -e 'rock' --and -e 'stone' dir
This only matches files that have both rock and stone in them. Lines are output that have rock or stone, or you can use option -l to just list files. The -F option searches strings (like grep -F and fgrep), --files applies the --and file-wide, which you want instead of applying the --and per line. Note that we have more than one pattern in this case, so option -e should be used (like grep also requires this).
A shorter form with --bool:
ugrep -F --files --bool 'rock stone' dir
where --bool formulates a Boolean query with space as AND (or use AND).
If you want to search directory dir recursively in subdirectories, use option -r.

What do the last two entries of PATH tell you?

I'm still learning how PATH works, what exactly is echo $PATH's output meant to be? What do they tell us?
What exactly is echo $PATH's output meant to be?
The current path.
What do the last two entries tell you?
The last two directories on your path.
In other words, it's unclear what you're asking. Do you not know what a path is? Are you asking what a particular sequence of special characters mean in the context of a path? What is the explicit path you're asking about?
$PATH variable is simply a list of paths that your system automatically checks whenever you run a command on, say your bash terminal.
PATH is a colon : (Unix-like) or semi-colon ; (Windows) separated list.
Whenever you run a command like ls -lrt, your system looks for the definition of the command (or function) ls. So the definition of the PATH variable being established, we can answer your two questions:
what exactly is echo $PATH's output meant to be
The $PATH's output provides a list of paths.
What do the last two entries of PATH tell you?
PATH is list is of all the paths where your system will look for a command. So the last 2 entries tell you the last 2 paths out of the list.

Find the name of the file or files with a certain text. This command can search through the directory and all sub directories to find all matches

Trying to find the name of a file by searching for a word that's in the file.
I have tried to look at many examples online but unfortunately I couldn't find a code that outputs the names of the files with that certain word in it.
grep -r 'Facebook' *
I expected the output to be many names of the files which has the word facebook in it but instead I got output of lines with the word facebook in it which is not what I wanted.
There are many possible solutions in a Unix/Linux environment:
find /path/to/base -name Facebook
ls -R /path/to/base | grep -i "[Ff]acebook"
etc.
Or there are programmatic approaches written in a language of your choice. Add more details about what you are trying to do for a better answer.
it should be something like this
grep -l "Facebook" *
this is going to search for all the files and not sub directories in the current folder and produce the name of the file where a match was found
from man page of grep:
-L, --files-without-match
Suppress normal output; instead print the name of each input file from which no output would normally have been printed. The scanning will stop on the first match.
-l, --files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning will stop on the first match. (-l is
specified by POSIX.)

Bash - grep command inconsistent with man page

I am trying to understand and read the man page. Yet everyday I find more inconsistent syntax and I would like some clarification to whether I am misunderstanding something.
Within the man page, it specifies the syntax for grep is grep [OPTIONS] [-e PATTERN]... [-f FILE]... [FILE...]
I got a working example that recursively searches all files within a directory for a keyword.
grep -rnw . -e 'memes
Now this example works, but I find it very inconsistent with the man page. The directory (Which the man page has written as [FILE...] but specifies the use case for if file == directory in the man page) is located last. Yet in this example it is located after [OPTIONS] and before [-e PATTERN].... Why is this allowed, it does not follow the specified regex fule of using this command?
Why is this allowed, it does not follow the specified regex fule of using this command?
The lines in the SYNOPSIS section of a manpage are not to be understood as strict regular expressions, but as a brief description of the syntax of a utility's arguments.
Depending on the particular application, the parser might be more or less flexible on how it accepts its options. After all, each program can implement whatever grammar they like for their arguments. Therefore, some might allow options at the beginning, at the end, or even in-between files (typically with ways to handle ambiguity that may arisa, e.g. reading from the standard input with -, filenames starting with -...).
Now, of course, there are some ways to do it that are common. For instance, POSIX.1-2017 12.1 Utility Argument Syntax says:
This section describes the argument syntax of the standard utilities and introduces terminology used throughout POSIX.1-2017 for describing the arguments processed by the utilities.
In your particular case, your implementation of grep (probably GNU's grep) allows to pass options in-between the file list, as you have discovered.
For more information, see:
https://unix.stackexchange.com/questions/17833/understand-synopsis-in-manpage
Are there standards for Linux command line switches and arguments?
https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html
You can also leverage .
grep ‘string’ * -lR

How to determine which pattern in a file matched with grep?

I use procmail to do extensive sorting on my inbox. My next to last recipe matches the incoming From: to a (very) long white/gold list of historically good email addresses, and patterns of email addresses. The recipe is:
# Anything on the goldlist goes straight to inbox
:0
* ? formail -zxFrom: -zxReply-To | fgrep -i -f $HOME/Mail/goldlist
{
LOG="RULE Gold: "
:0:
$DEFAULT
}
The final recipe puts everything left in a suspect folder to be examined as probable spam. Goldlist is currenltty 7384 lines long (yikes...). Every once in a while, I get a piece of spam that has slipped through and I want to fix the failing pattern. I thought I read a while ago about a special flag in grep that helped show the matching patterns, but I can't find that again. Is there a way to use grep that shows the pattern from a file that matched the scanned text? Or another similar tool that would answer the question short of writing a script to scan pattern by pattern?
grep -o will output only the matched text (as opposed to the whole line). That may help. Otherwise, I think you'll need to write a wrapper script to try one pattern at a time.
I'm not sure if this will help you or not. There is a "-o" parameter to output only the matching expression.
From the man page:
-o, --only-matching
Show only the part of a matching line that matches PATTERN.

Resources