why does this grep command have no output? - grep

If I use a grep command like this ls | grep '^[-[:alnum:]\._]+$' to match filenames, it outputs no result but when the command changes to ls | grep '^[-[:alnum:]\._]*$', it works correctly. What's going on?

grep uses "basic" regexes by default, where + is a normal character. You need \+ to match 1 or more things (or use grep -E).

Related

grep for pattern with special character and output only matched string

Team,
I want to grep for a substring container - and then only output that string and not whole line. how can i? I know i can awk on space and pull using $ but want to know how to do in grep?
echo $test_pods_info | grep -F 'test-'
output
test-78ac951e-89a6-4199-87a4-db8a1b8b054f export-9b55f0d5-071d-431-1d2ux0-avexport-xavierisp-sjc4--a4dd85-102 1/1 Running 0 19h
expected output
test-78ac951e-89a6-4199-87a4-db8a1b8b054f
awk is more suitable for this as you want to get first field in a matching line:
awk '/test-/{print $1}' <<< "$taxIncluded"
test-78ac951e-89a6-4199-87a4-db8a1b8b054f
If you really want to use grep then this might be what you're looking for:
grep -o 'test-\S*' <<< "$taxIncluded"
or:
grep -o 'test-[^[:space:]]*' <<< "$taxIncluded"
Try
echo $test_pods_info | grep -o 'test-'
the -o option is:
show[ing] only the part of a line matching PATTERN
according to grep --help. Of course, this will only print test-, so you'll need to rework your regex:
grep -oE '(test).*[[:space:]]\b'
Figured it out..
echo $test_pods_info | grep -o "\test-\w*-\w*\-\w*\-\w*\-\w*"
outoput
test-78ac951e-89a6-4199-87a4-db8a1b8b054f
but i wish there is simple way. like \test-*\

Grep redirection is pulling more information that I want in log.txt

I want the output of the sed file edit to go into my log file name d_selinuxlog.txt. Currently, grep outputs the specified string as well as 3 other strings above and below in the edited file.
#!/bin/bash
{ getenforce;
sed -i s/SELINUX=enforcing/SELINUX=disabled /etc/selinux/config;
grep "SELINUX=*" /etc/selinux/config > /home/neb/scropts/logs/d_selinuxlog.txt;
setenforce 0;
getenforce; }
I want to be seeing just SELINUX=disabled in the log file
All the lines with the lines SELINUX are going to match, even the commented ones, so, you need to omit that ones, and the * from the match.
grep "SELINUX=" /etc/selinux/config | grep -v "#"
This is my output
17:52:07 alvaro#lykan /home/alvaro
$ grep "SELINUX=" /etc/selinux/config | grep -v "#"
SELINUX=disabled
17:52:22 alvaro#lykan /home/alvaro

print filename if several matches are present in file

I want to print the filename if only ALL the matches are present... on different lines
grep -l -w '10B\|01A\|gencode' */$a*filename.vcf
this prints out the filename, but not only if ALL three matches are present.
Would you consider to try awk? awk may solve it in following method,
awk '/10B/&&/01A/&&/gencode/{print FILENAME}' */$a*filename.vcf
try following, just edited your solution a bit.
grep -l '10B.*01A.*gencode' Input_file
With grep and its -P (Perl-Compatibility) option and positive lookahead regex (?=(regex)), to match patterns if in any order.
grep -lwP '(?=.*?10B)(?=.*?01A)(?=.*?gencode)' /path/to/infile
grep -l 'pattern1' files ... | xargs grep -l 'pattern2' | xargs grep -l 'pattern3'
From the grep manual:
-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.)

Simple way to order grep's result by time (reverse)?

I often have to look for specific strings in a big set of log files with grep. And I get lots of results, on what I must scroll a lot.
Today, the results of grep list the results in alphabetical order. I would like to have my grep results reversed ordered by time, like a ls -ltr would do.
I know I could take the result of ls -ltr and grep file by file. I do it like this:
ls -ltr ${my_log_dir}\* | awk '{print $9}' |xargs grep ${my_pattern}
But I wonder: Is there a simpler way?
PS: I'm using ksh on AIX.
The solution I found (thanks to Fedorqui) was to simply use ls -tr. It assumes the results are passed in the right order through the | to xargs allowing then to do the grep.
My misconception was that since when I us ls, the results arrive not as a single column list but as a multiple column list, it couldn't work as an input for xargs.
Here is the simplest solution to date, since it avoids any awk parsing:
ls -tr ${my_log_dir}\* | xargs grep ${my_pattern}
I checked, and every result of the ls -t are passed to xargs even though they look not as I expected they would enter easily in it:
srv:/papi/tata $ ls -t
addl ieet rrri
ooij lllr sss
srv:/papi/tata $ ls -t |xargs -I{} echo {}
addl
ieet
rrri
ooij
lllr
sss
This will work too use find command:-
find -type f -print0 | xargs -r0 stat -c %y\ %n | sort -r | awk '{print $4}' | sed "s|^\./||"
-print0 in find to preserve files having special characters(whitespaces, tabs)
Print file status (stat with %y (Time of last modification) and %n (%n File name) with output having new-separated (-c)
Reverse sort the output from previous command. (-r for reverse)
awk '{print $4}' printing only the file-name (can be optimized as needed)
Removing the leading ./ from the file-names.

Grep digits after match

I would like to grep digits inside a set of parentheses after a match.
Given foo.txt below,
foo: "32.1" bar: "42.0" misc: "52.3"
I want to extract the number after bar, 42.0.
The following line will match, but I'd like to extract the digit. I guess I could pipe the output back into grep looking for \d+.\d+, but is there a better way?
grep -o -P 'bar: "\d+.\d+"' foo.txt
One way is to use look ahead and look-behind assertions:
grep -o -P '(?<=bar: ")\d+.\d+(?=")'
Another is to use sed:
sed -e 's/.*bar: "\([[:digit:]]\+.[[:digit:]]\+\)".*/\1/'
You could use the below grep also,
$ echo 'foo: "32.1" bar: "42.0" misc: "52.3"' | grep -oP 'bar:\s+"\K[^"]*(?=")'
42.0

Resources