Hot answers tagged

29

There are two problems with your example. The primary one is that you're assuming that regular expressions work the same as glob patterns in that * is a wildcard meaning "any sequence of characters." In regular expressions, * means "any number of the previous atom" instead, so fil* means f followed by i followed by zero or more l characters. You need to say ...


12

That's grep issue, not find. grep matches pattern using regular expression by default, the pattern schema_name. means any character follows the string schema_name. If you want to match the dot . literally, you have to escape it with a backslash \: find . -type f -name "*.sql" -exec grep -il 'schema_name\.' {} + or using -F option: find . -type f -name ...


11

Replace your expression to match a pattern (i.e. /&&&key word&&&/) by another expression explicitly using $0, the current line: tolower($0) ~ /&&&key word&&&/ or toupper($0) ~ /&&&KEY WORD&&&/ so you have awk 'tolower($0) ~ /&&&key word&&&/ { p = ! p ; next ...


9

gawk has an IGNORECASE builtin variable, which, if set to nonzero, causes all string and regular expression comparisons to be case-insensitive. You could use that: BEGIN{IGNORECASE=1} /&&&key word&&&/ { foo bar baz } etc. This is specific to gawk, though, but I find it to be more readable than the (more portable) alternative by ...


9

grep -vxE '([0-9]{5}[,-])*[0-9]{5}' Would report the incorrect lines. Or if you also want to forbid 12345-12345-12345: num='[0-9]{5}' num_or_range="$num(-$num)?" grep -vxE "($num_or_range,)*$num_or_range"


9

awk substitution capabilities are quite limited. gawk has gensub() that can at least include parts of the matched portion in the replacement, but no operation can be done on those. It's possible with awk, but you need to take a different approach: awk '{ text = $0 $0 = "" while (match(text, /[0-9]+/)) { $0 = $0 substr(text, 1, RSTART-1) \ ...


6

Your awk solution matches only the first number and then replaces all other number with the first number reduced by one. Taking your program, you can use with GNU's awk (gawk): awk 'BEGIN { RS="[^0-9]"; OFS=""; ORS=""; } {a=gensub(/([0-9]+)/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+/,(a-1),$0);} print $0,RT}' But this can be simplified to awk 'BEGIN { ...


5

sed does not understand \d. You can use [0-9] or, more generally, [[:digit:]] in its place: $ sed -r 's/.*(X[[:digit:]])(.*)45.*/\1\2/' test.txt X1yad X2fad X3had X4wad X5mad


5

The problem are the single quotes. Variables aren't expanded in single quotes (from man bash): Enclosing characters in single quotes preserves the literal value of each character within the quotes. If you want to use a variable, you need double quotes. To illustrate: $ foo="bar" $ echo '$foo' $foo $ echo "$foo" bar So, in your case, you want ...


4

The feature you are looking for is there. You are just missing a * in your example. Type cat file000[1-3]*ESC* and it should work. I think this is the case because the readline function insert-completions (which is bound to ESC*) will not expand the glob pattern if it does not match any files. And without the last * it does not match the files. You can read ...


4

You could use fgrep find . -type f -name "*.sql" -exec fgrep -i -l 'schema_name.' {} + which on older Unix operating systems may very well be a lot faster (fgrep, grep and egrep used to be 3 different executables, and there fgrep was a lot faster because it omitted everything related to regex entirely - on eg GNU based systems these three programs are ...


4

For a good grep solution, see St├ęphane's answer. As an alternative, here's a Perl one: perl -ne 'print if grep{$_!~/^\d{5}$/} split(/[,-]/); ' file That will split each input line on , or - and then will look for members of the split array that don't consist of exactly 5 numbers. If any are found, the line is printed.


3

You need perl regular expressions for this. With a grep that supports the -P flag: grep -oP '(?<=a)a' file | wc -l This is a positive lookbehind. It matches a single a which is preceded by another a. If you prefer perl (or your grep doesn't support the -P flag): perl -ne 'while(m/(?<=a)a/g){$a++}END{print "$a\n"}' file Example: $ cat file ...


3

Let's see if sed is right tool for this job: sed '/^~[[:alpha:]].*/!{ # if line doesn't match this pattern H # append it to hold space $!d # and delete it if it's not the last line b end # else branch to label end } //b end ...


2

Escape the dot in the grep search pattern: find . -type f -name "*.sql" -exec grep -i -l 'schema_name\.' {} +


2

You can count repeated pairs of letters such as your example aa in a data file big_file like this: tr -cs a '\012' <big_file | awk '/aa/{n += length - 1}; END {print n+0}' The line can be explained like this The tr changes any sequence of characters that is not a into a newline. This splits multiple occurrences of aa... onto separate lines The awk ...


2

You don't need cat. Does this do what you want: $ grep -v -E '^([0-9]{5}(,|-))+' <FILE> For example, if FILE had the following contents: 12345,23456,34567-45678,12345-23456,34567 1,2 12345*23456,34567-45678,12345-23456,34567 123456 1234*23456,34567-45678,12345-23456,34567 result would be: $ grep -v -E '^([0-9]{5}(,|-))+' 5d 1,2 ...


2

A dot . means any character. But you don't want it to match a double quote; you want it to match anything but a double quote. So specify that with a character class: sed 's/"[^"]*"/"x"/g'


2

sed -E 's/" rel="lightbox\[[0-9]+\]" title="/#/g' filename


2

grep only selects lines based on the regular expression specified and prints them. I think you are forced to pipe the output lines and use an additional command to do the job. Usually you would use sed or awk to do the job without grep, because they can both select lines and replace strings. There is a solution below using awk: awk -v word=cat -v n=2 ...


2

You can use either of these, depending on what you're trying to display: $ echo "lol llol" | grep -E "\blol" lol llol $ echo "lol llol" | grep -Eo "\blol" lol Putting the regex in quotes solves your matching problem. The -o flag causes grep to only print the matched string instead of the entire line.


2

As is often the case on Solaris, /usr/bin/egrep is a legacy implementation that isn't POSIX-compliant, while /usr/xpg4/bin/egrep is a POSIX-compliant implementation and has little if anything beyond POSIX. Unless you're running legacy Solaris applications from the pre-POSIX days, make sure that /usr/xpg4/bin is before /usr/bin in your $PATH. GNU tools ...


1

sed 's/abcd\(X[0-9][a-z]ad\)45das/\1/g' your_file_name should do it.


1

Using generic (non-GNU) "awk": I would suggest a separation of the input lines into arrays of values and separators. Then, modify the values and recombine them with the separators: awk '{ split("0," $0 ",0", numbers, "[^0-9]+"); # make sure each line starts and ends with a number split($0, sep, "[0-9]+"); res = ""; j = 1; for (i = 2; i < ...


1

Use the environment variable LESS, overriding it for the single command you are running. See also: LESS='+/LESS[[:space:]]*Options' man less LESS='+/\+cmd' man less LESS='+/optional variable assignments' man bash LESS=+/SIMPLE\ COMMAND\ EXPANSION man bash I also discussed this more generally in a Meta post a while back: How can I link people to ...


1

Using the perl regexp engine (you did not specify what you are using), this can be achieved with: perl -pe 's/^(.*?)( \(|-tt).*/\1/' < indata.txt The trick is to make the first .* match non-greedy with .*?, or it will consume the year part for any line that has both a year and the -tt id.


1

Why does the grep command ignore the period in the search string? It doesn't. To prove, run grep . file which is an easy way to remove all empty lines from file. In other words, . is the regex atom for any single character (except newline). To literally match a dot, the atom must be escaped as \.


1

If you put the "^" outside the quotes, your shell could interpret it as a redirection. Quoting it avoids that problem. That is considered obsolete, but you can find it mentioned, e.g., in the changelog for fish: The caret ^ now only does a stderr redirection if it is the first character of a token, making git users happy #168 Further reading: ...


1

There shouldn't be any difference between the commands. They both run exactly the same thing: $ set -x ## turn on debugging info $ /bin/grep ^'\<that\>' file.txt + /bin/grep '^\<that\>' file.txt $ /bin/grep '^\<that\>' file.txt + /bin/grep '^\<that\>' file.txt As you can see above, both versions end up running the exact same ...


1

The command you are looking for is: find / -name "*partname*" find searches by default recursively through subfolders. Here is the first result on google for a find tutorial. If you want to know all the details about find, just type the following to get to the manpage: man find exit by pressing q search through the page with /searchterm



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