
Note that \2 only matches the last digit on the line as the preceding. (This order was placed for QT300)(0)(! OK?) Insert Found value: in front of any line containing a digit, and print those lines up to the end of the 3rd digit found (or to at most the 3rd digit may output fewer digits at the end if there are fewer consecutive digits in the first substring of digits on the line): $ sed -n '/]/s/\(]*]\\)\(.*\)/(\1)(\2)(\3)/' line.txt Insert Found value: in front of any line containing a digit, and print those lines: $ sed -n '/]/s/^/Found value: /p' line.txtįound value: This order was placed for QT3000! OK? new line at the beginning is a blank line and new line at end applies to every line in the file. Regular expressions Regular expressions (regex) are a domain-specific language for finding patterns and are one of the key functionalities in scripting languages such as Python, as well as the UNIX utilities sed, awk, and grep. You want to use sed because grep can only print matching lines (or words), but not really modify the data matched. bash grep newline Share Improve this question Follow asked at 12:06 tuxnani 3,634 6 21 33 6 It's not clear what you want. To get the three different outputs that you show in the question, use sed rather than grep. For the difference between these, please see Difference between, ] and \d. This means that to extract all lines that contains (at least) one digit, you may instead use the pattern ] or, or \d if you want to keep using Perl-like expressions with GNU grep, with no other decorations. The + isn't needed either as a single digit would be matched by the preceding expression (a single digit is "one or more digits"). Likewise, the parentheses are not needed at all as they serve no function in the pattern. Since regular expressions matches on substrings, as opposed to filename globbing patterns which are always automatically anchored, neither of the. This is better written as ] or as the range (in the POSIX standard locale). It first of all uses a non-standard expression to match a digit, \d. You then applied this in searching for matches in both the files mentioned on the command line.Ī secondary issue was the \\d in the pattern.txt file, which matches a backslash followed by the character d, i.e. This means that -e -f will be interpreted as "the regular expression to use is -f". The -e option is used for explicitly saying "the next argument is the expression".

The issue with your command was that you used -e -f. I.e., search in line.txt for lines matching any of the extended regular expressions listed in pattern.txt, which, given the data in the question, produces This order was placed for QT3000! OK? You use single quotes to prevent the shell from doing interpolation which you may have to do if your regular expression used as part of the pattern. Single quotes prevent the shell variable from being interpolated by the shell. Then, using it with GNU grep would be a matter of grep -E -f pattern.txt line.txt 1 Answer Sorted by: 75 You need to use double quotes. The captured subsequence may be used later in the expression, via a back reference, and may also be retrieved from the matcher once the match operation is complete.Īssuming that the pattern in pattern.txt is (.*)(\d+)(.*) Group zero always stands for the entire expression.Ĭapturing groups are so named because, during a match, each subsequence of the input sequence that matches such a group is saved. In the expression ((A)(B(C))), for example, there are four such groups: Perhaps grep doesn't have such notion as: Groups and capturingĬapturing groups are numbered by counting their opening parentheses from left to right. Utilizing something similar to m.group(0) from a tutorial on regex. This order was placed for QT3000! regex]$ Using line.txt and pattern.txt as below: regex]$ grep -e -f pattern.txt regex]$ cat regex]$ cat line.txt Or Found value: This order was placed for QT300 The awk/ sed/ perl ones don't reflect whether any line matched the patterns in their exit status.How would I get this output: Found value: This order was placed for QT3000! OK? Please beware that all those will have different regular expression syntaxes.

Or perl: perl -ne 'print if /pattern1/ & /pattern2/'

Or with sed: sed -e '/pattern1/!d' -e '/pattern2/!d'
#Shell grep regex portable
The best portable way is probably with awk as already mentioned: awk '/pattern1/ & /pattern2/' If the patterns don't overlap, you may also be able to do: grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1' *s as & matches strings that match both and exactly, a&b would never match as there's no such string that can be both a and b at the same time). With ast grep: grep -X '.*pattern1.*&.*pattern2.*'

With GNU grep, when built with PCRE support, you can do: grep -P '^(?=.*pattern1)(?=.*pattern2)' To find the lines that match each and everyone of a list of patterns, agrep (the original one, now shipped with glimpse, not the unrelated one in the TRE regexp library) can do it with this syntax: agrep 'pattern1 pattern2'
