Tag Info

Hot answers tagged

31

grep by default searches standard input if no files are given: grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN. By default, grep prints the matching lines. If you just do grep doc grep expects standard input to ...


21

Your suspicion is correct; the exit status of the last command of the script will be passed to the calling environment. So the answer is that this script will return an exit status 0 if grep matched someting in the data, exist status 1 if there was no match, and exit status 2 if some error occurred.


21

The point of grepping output that is thrown away is that the writer only wants the return status of grep. He/She only wants to know whether a pattern matched or not. In your case, the last grep checks if the earlier command's output contains any lines start with 200. In modern POSIX system, you can do it all with grep -q without redirecting to /dev/null: ...


18

Quote the argument to grep, thus ls -a | grep '^\.' The reason for this is that the shell handles \. and turns it back into plain ., which grep then treats as a single-character wildcard. If in doubt, always quote a string that contains (or might contain) a character that's special to the shell.


13

grep is waiting for input. From man grep: [...] DESCRIPTION grep searches the named input FILEs (or standard input if no files are named [...]


11

You need to put the grep regex inside quotes. ls -a | grep '^\.' Note: Don't parse the output of ls command.


9

How about using cut? If you'd like to print the 2nd pattern echo "$above_string" | cut -f2 -d "?" Second column onward echo "$above_string" | cut -f2- -d "?"


8

You could use grep -o to print only the matching part and use the result as patterns for a second grep -v on the original patterns.txt file: grep -oFf patterns.txt Strings.xml | grep -vFf - patterns.txt Though in this particular case you could also use join + sort: join -t\" -v1 -j2 -o 1.1 1.2 1.3 <(sort -t\" -k2 patterns.txt) <(sort -t\" -k2 ...


8

awk (assuming your implementation supports the nextfile statement) can do this quite nicely: awk 'FNR > 50 { nextfile }; /foobar/ { print FILENAME ": " $0 }' ./*.sql The first statement skips to the next file once 50 records have been processed. The second statement prints the filename and the matching line for any line containing foobar. If your awk ...


7

You have a file called a in your current directory. you haven't quoted the RE passed to grep, so this is what is happening: Given grep [aeiou] file1 The shell sees [aeiou] and because it's a valid (glob) pattern it tries to match that against a single letter file a, e, i, o, u. Since it succeeds it replaces the parameter with the file it matched, a. The ...


6

grep searches for the first argument (the pattern) in the files passed on the command line or stdin if no files are passed. Without the quote your shell will expand lect* to all the files in the directory that begin with lect. Your command will then be: grep lect1.txt lect2.doc lect3.doc which means search for the text lect1.txt in both .doc files. ...


6

Try this: touch -d"April 13 3 AM" file1 touch -d"April 13 9 AM" file2 find . -newer file1 ! -newer file2 -exec grep -l "pcV6URY" {} + rm file1 file2 How it works find can work directly with times but touch handles human-style dates better: touch -d"April 13 3 AM" file1; touch -d"April 13 9 AM" file2 This creates two files to mark the beginning and end ...


6

GNU grep's -w will only consider the 26+26+10+1 (ASCII letters, digits and underscore) as word constituents. You can't change that, even by using a different locale (even in a locale where é is considered a letter, Stéphane would still be St and phane separated by the non-word é). You can however implement that logic by hand: grep -E ...


4

The best solution for this is to use awk: $ ldd /usr/bin/ppdhtml | awk '/ => / { print $1 }' | head -n1 libcupsppdc.so.1 To do this using grep, you will need to use the lookahead and lookbehind features of PCRE: $ ldd /usr/bin/ppdhtml | grep -Po '(?<=\t).+(?= => )' | head -n1 libcupsppdc.so.1 The lookahead and lookbehind features affect that ...


4

Using Awk to print the second and third records separated by newlines: awk -F"?" '{printf "%s\n%s\n", $2,$3}' Elvis August 16 Leonard Nimoy February 27 If you want to swap out the record, you can set it as a variable: awk -v record=2 -F"?" '{print $record}' Elvis August 16


4

echo $above_string | grep -oP "^([^?]*\?){2}\K[^?]*" Change 2 to the n - 1 value in order to obtain the nth string. This assumes that you want the nth string in that line. You have n - 1 strings with no ? ending with a literal '?' (\? since it's a special character in perl regex). Then with \K you state you are not interested in the previous contents, ...


4

sounds like you're not using proper simple quote ('). Try to copy and paste this one: grep -E '( ^ | [[:space:]] )[A-Z]{2}[[:digit:]]{2}((- | [[:space:]] )[[:alnum:]]{4}) {3} ' (I have the same error in bash if I copy and paste your script, which use ’ instead of ')


4

This solution works, but I feel that it is clumsy. Searching the first 50 lines for the string "foobar": $ for I in *.sql ; do echo $I && head -n 50 $I | grep foobar ; done


3

Your Awk pattern is failing because the word "profile" does not start the record, [profile does... awk '/^\[profile/ {gsub(/]/,""); print $2}' test.txt dev prod Another approach would be to load an array, using split: awk -F'[][]' '/profile/ {p=split($2,profiles," "); print profiles[2]}' test.txt dev prod


3

With sed you can do: sed '/\n/P;//d;s/[^?]*/\n&\n/[num];D' ...where you would replace the [num] above with some number representing the desired occurrence. If the numbered occurrence you specify does not exist, as is demonstrated in the following example, sed will simply print nothing at all. echo ,2,3 | sed '/\n/P;//d;s/[^,]*/\n&\n/4;D' Above ...


3

Perl solution: perl -ne '$id = "6d87de8e-1276-4496-b49d-dd4cd375cbe4"; print if $match = (/IDA:$id/ .. /IDA:(?!$id)/) and $match !~ /E0$/ ' *.log Explanation: /regex1/ .. /regex2/ returns true for lines between the matches. IDA:(?!$id) meand IDA: not followed by $id. the last line in a range is denoted by the E0 suffix ...


3

If there is only one foo3 in line sed -n '/foo3=/{s/.*foo3=//;s/\S*=.*//;p}' file.txt Suppress printing any line (-n options) exept which pushed by p. For lines which consists foo3=: Exchange everything before foo3= with it included (.*foo3=) to nothing (//). Remove everything which starts with some(*) non-space (\S) symbols with =. Prints resedue ...


3

Add a word boundary assertion: grep -Eo '\bApple_1\b'


3

The best approach is probably what @don_crissti suggested, so here's a variation on the same theme: $ grep -vf <(grep -Po 'name=\K.+?"' Strings.xml) patterns.txt "ExitWarning" "SomeMessage" "Help" This basically is the inverse of @don_crissti's approach. It uses grep with Perl Compatible Regular Expressions (-P) and the -o switch to print only the ...


3

I think awk could help: awk 'BEGIN { sd = "20150408T13:29:28"; ed = "20150408T17:55:02"; } $1 "T" $2 >= sd && $1 "T" $2 <= ed' log


2

sed '/^foo3=/P;/\n/!s/[^ ]\{1,\}=/\n&/g;D' <infile >outfile You may have to use a literal newline in place of the n above, but this will print only the contents between foo3 and foo4. For faster processing, get more explicit about it: sed '/\n/s/ [^ ]*=.*//p;/\n/!s/foo3=/\n\n&/;D' | grep . Or with an extra grep the top can be much faster ...


2

According to your data samples in your question this seems to be what you want (otherwise clarify your question, please): awk '$5 > max { max = $5 ; out = $0 } END { print out }' datafile This will print that line in datafile where the value in the 5th column is the maximum. The program works as follows: For each line the fifth column element will be ...


2

All you need is sort macadd | uniq -c as explained by @roaima but I just wanted to point out how you could do it using the same approach you had attempted. There's no reason to grep through the file, you can just feed it directly to while: while read mac; do echo "$mac"; done < macadd Also, grep has a -c option which counts matches. So, with a couple ...


2

You have to use \s instead of \w (which match a word character) to match any single character considered whitespace, include [\t\n\f\r ]: ldd /usr/bin/ffmpeg | grep -oP "^([a-z0-9.-]|\s)*" or: ldd /usr/bin/ffmpeg | grep -oP "^\s*[a-z0-9.-]*"


2

sed You can use sed for this, but it is not advisable, e.g. here is a zero-based solution that uses a quantifier to select the desired field: n=1 sed 's/\([^?]*? *\)\{'$n'\}//; s/?.*//' <<<"$above_string" Output: Elvis August 16



Only top voted, non community-wiki answers of a minimum length are eligible