I have a txt file that has only information about location (location.txt)
Another large txt file (all.txt) has a lot of information like id , and a location.txt is subset of all.txt ( some records common in both )
I want to search the location.txt in another file with grep (all.txt)
and print all common records ( but all information like all.txt )
I try to grep by :
grep -f location.txt all.txt
the problem grep just give me the last location not all locations
how can I print all location?
I'm assuming you mean to use one of the files as a set of patterns for grep. If this is the case, you seem to be looking for a way to print all lines in one file not found in the other and this is what you want:
grep -vFf file_with_patterns other_file
Explanation
-F means to interpret the pattern(s) literally, giving no particular meaning to regex metacharacters (like * and +, for example)
-f means read regex patterns from the file named as argument (file_with_patterns in this case).
Related
I created a test file with the following:
<cert>
</cert>
I'm now trying to find this with grep and the following command, but it take forever to run.
How can I search quickly for files that contain adjacent lines like these?
tr -d '\n' | grep '<cert></cert>' test.test
So, from the comments, you're trying to get the filenames that contain an empty <cert>..</cert> element. You're using several tools wrong. As #iiSeymour pointed out, tr only reads from standard input-- so if you want to use it to select from lots of filenames, you'll need to use a loop. grep prints out matching lines, not filenames; though you could use grep -l to see the filenames instead.
But you're only joining lines because grep works one line at a time; so let's use a better tool. Here's how to search with awk:
awk '/<cert>/ { started=1; }
/<\/cert>/ { if (started) { print FILENAME; nextfile;} }
!/<cert>/ { started = 0; }' file1 file2 *.txt
It checks each line and keeps track of whether the previous line matched <cert>. (!/pattern/ sets the flag back to zero on lines not matching /pattern/.) Call it with all your files (or with a wildcard like *.txt).
And a friendly suggestion: Next time, try each command separately (you've been stuck on this for hours and you still don't know what grep does?). And have a quick look at the manual for the tools you want to use. Unix tools are usually too complex for simple trial and error.
Any help would be greatly appreciated. I can read code and figure it out, but I have trouble writing from scratch.
I need help starting a ksh script that would search a file for multiple strings and write each line containing one of those strings to an output file.
If I use the following command:
$ grep "search pattern" file >> output file
...that does what I want it to. But I need to search multiple strings, and write the output in the order listed in the file.
Again... any help would be great! Thank you in advance!
Have a look at the regular expression manuals. You can specify multiple strings in the search expression such as grep "John|Bill"
Man grep will teach you a lot about regular expressions, but there are several online sites where you try them out, such as regex101 and (more colorful) regexr.
Sometimes you need egrep.
egrep "first substring|second substring" file
When you have a lot substrings you can put them in a variable first
findalot="first substring|second substring"
findalot="${findalot}|third substring"
findalot="${findalot}|find me too"
skipsome="notme"
skipsome="${skipsome}|dirty words"
egrep "${findalot}" file | egrep -v "${skipsome}"
Use "-f" in grep .
Write all the strings you want to match in a file ( lets say pattern_file , the list of strings should be one per line)
and use grep like below
grep -f pattern_file file > output_file
I am trying to grep the output of a command that outputs unknown text and a directory per line. Below is an example of what I mean:
.MHuj.5.. /var/log/messages
The text and directory may be different from time to time or system to system. All I want to do though is be able to grep the directory out and send it to a variable.
I have looked around but cannot figure out how to grep to the end of a word. I know I can start the search phrase looking for a "/", but I don't know how to tell grep to stop at the end of the word, or if it will consider the next "/" a new word or not. The directories listed could change, so I can't assume the same amount of directories will be listed each time. In some cases, there will be multiple lines listed and each will have a directory list in it's output. Thanks for any help you can provide!
If your directory paths does not have spaces then you can do:
$ echo '.MHuj.5.. /var/log/messages' | awk '{print $NF}'
/var/log/messages
It's not clear from a single example whether we can generalize that e.g. the first occurrence of a slash marks the beginning of the data you want to extract. If that holds, try
grep -o '/.*' file
To fetch everything after the last space, try
grep -o '[^ ]*$' file
For more advanced pattern matching and extraction, maybe look at sed, or Awk or Perl or Python.
Your line can be described as:
^\S+\s+(\S+)$
That's assuming whitespace is your delimiter between the random text and the directory. It simply separates the whitespace from the non-whitespace and captures the second part.
Or you might want to look into the word boundary character class: \b.
I know you said to use grep, but I can't help to mention that this is trivially done using awk:
awk '{ print $NF }' input.txt
This is assuming that a whitespace is the delimiter and that the path does not contain any whitespaces.
I have a file with a list of word and I want to identify only the word in the file which exactly matches another word?
So, for example, if I have in the file, the words "BEBE, BEBÉ, BEBÉS", and I look for "BEBE", I want it to return just the first one, which is the exact match.
I tried using grep -w "BEBE" filename.txt, but it doesn't work. It still gives me back all three of them.
Use -o to only display the part that matches with -w, also use -F for fixed string if you're not regex matching:
$ cat file
BEBE, BEBÉ, BEBÉS
$ grep -woF 'BEBÉ' file
BEBÉ
$ grep -woF 'BEBÉS' file
BEBÉS
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
grep is used to search within a file to see if any line matches a given regular expression. However, I have this situation - I want to write a regular expression that will match the filename itself (and not the contents of the file). I will run this from the system's root directory, to find all those files that match the regular expression.
For example, if I want to find all Visual Basic form files that start with an "f" and end with .frm, I'll use the regular expression -
"f[[:alnum:]]*\.frm"
Can grep do this? If not, is there a utility that would let me do this?
You need to use find instead of grep in this case.
You can also use find in combination with grep or egrep:
$ find | grep "f[[:alnum:]]\.frm"
Example
find <path> -name '*FileName*'
From manual:
find -name pattern
Base of file name (the path with the leading directories removed) matches shell pattern pattern.
Because the leading directories are removed, the file names considered for a match with -name will never
include a slash, so "-name a/b" will never match anything (you probably need to use -path instead). The
metacharacters ("*", "?", and "[]") match a "." at the start of the base name (this is a change in find‐
utils-4.2.2; see section STANDARDS CONFORMANCE below). To ignore a directory and the files under it,
use -prune; see an example in the description of -path. Braces are not recognised as being special,
despite the fact that some shells including Bash imbue braces with a special meaning in shell patterns.
The filename matching is performed with the use of the fnmatch(3) library function. Don't forget to
enclose the pattern in quotes in order to protect it from expansion by the shell.
As Pablo said, you need to use find instead of grep, but there's no need to pipe find to grep. find has that functionality built in:
find . -regex 'f[[:alnum:]]\.frm'
find is a very powerful program for searching for files by name and supports searching by file type, depth limiting, combining different search terms with boolean operations, and executing arbitrary commands on found files. See the find man page for more information.
You can find the relative path of a file using tree. Just pipe the output to grep to filter down:
tree -f | grep filename
Here is a function you can put into your .bash_profile, .bashrc, .zshrc or other...
findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
The easiest way is
find . | grep test
Here find will list all the files in the (.), i.e., the
current directory, recursively.
And then it is just a simple grep. All the files which name has "test" will appear.
You can play with grep as per your requirement.
Note: As the grep is a generic string classification. It can result in giving you not only file names. But if a path has a directory ('/xyz_test_123/other.txt') it would also be part of the result set.
find -iname "file_name"
Syntax:
find -type type_descriptor file_name_here
type_descriptor types:
f: regular file
d: directory
l: symbolic link
c: character devices
b: block devices
find . | grep KeywordToSearch
Here . means the current directory which is the value for the path parameter for the find command. It is piped to grep to search the keyword which should return all matching results.
Note: This is case sensitive. So for example fileName and FileName are not same.
You can also do:
tree | grep filename
This pipes the output of the tree command to grep for a search. This will only tell you whether the file exists though.
Also for multiple files.
tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
No, grep works just fine for this:
grep -rl "filename" [starting point]
grep -rL "not in filename"