Tag Info

New answers tagged

0

If you search for a verbatim string, and want to be sure that the string you passed is interpreted verbatim (i.e. without risking that say a dot or question mark will be interpreted as something else) use fgrep or egrep -F. As for the difference between egrep and grep, I think that egrep is most of the time the thing you want. The GNU manual site lists the ...


1

You can do this by listing both sets of packages and determining the disjunction of the two results: grep -Fxv -f <(apt list | grep unstable | cut -d/ -f1) <(apt list | grep experimental | cut -d/ -f1) Both cuts extract the package name from apt’s output. The first set of packages (from unstable) is given as a list of patterns for grep using the -f ...


1

If you use egrep that mean grep with extended regexp syntax so to be able to transfer your pattern into sed you have to add parametr -r(--regexp-extended) or -E in some versions. Regarding to your expression you have extra \ after c so even with egrep it does not match Additionally your better use \1 instead $1 for reverse-matching. So final command could ...


2

In your original statement the problem is that you're mixing syntactic and literal quotes: the single quotes within the double quotes will be matched literally. You'll want to either simply remove them or mix quotes (not nest them). Untested examples: sed 's/foo/{bar}/' sed "s/foo/"'{bar}'"/" There are many flavours of regular expressions, and they all ...


5

try ls -1 | grep -E '^[A-Z]?([a-z][A-Z])*[a-z]?$' EDIT: as pointed very correctly by @mikeserv, this won't work for non-ASCII chars. And indeed they do happen quite often (e.g. music files with foreign titles for filename). So the more robust way is: ls -1 | grep -E '^[[:upper:]]?([[:lower:]][[:upper:]])*[[:lower:]]?$' In the following, I retain just ...


2

set aAbBaBbA bAbBaA bbAb AAaBbAa BBBaaa aBaB l= u=; printf %s\\n "$@" | grep -E "^([${l:=[:lower:]}][${u:=[:upper:]}])+[$l]?$|^([$u][$l])+[$u]?$" OUTPUT: aAbBaBbA bAbBaA aBaB But see Pierre's answer for the (obviously) better version of this. Still, there is another way: grep -vE '[^[:alpha:]]|[[:lower:]]{2}|[[:upper:]]{2}|^$' ...though ...


0

The solution is grep -E '^([a-z][A-Z])+$'


3

Type this command: ls |grep -E '^([[:upper:]][[:lower:]])+[[:upper:]]?$|^([[:lower:]][[:upper:]])+[[:lower:]]?$' To break this down. ls is the main command It is piped to grep The switch -P or -E are telling grep to search using regular expressions (regex) Within the single quote ' and the parentheses () the pattern is layed out. Basically it reads ...


3

sed '/P1/,/P2/!d;/P2/q' ...would do the job portably by deleting all lines which do !not fall within the range, then quitting the first time it encounters the end of the range. It does not fail for P2 preceding P1, and it does not require GNU specific syntax to write simply.


3

In sed: sed -n '/P1/,/P2/p; /P2/q' -n suppresses the default printing, and you print lines between the matching address ranges using the p command. Normally this would match both the sections, so you quit (q) when the first P2 matches. This will fail if a P2 comes before P1. To handle that case, try: sed -n '/P1/,/P2/{p; /P2/q}'


3

with awk awk '/P1/{a=1};a;/P2/{exit}' file something P1 something content1 content2 something P2 something


1

Try this : perl -0ne 'print $& if /^Host.*?IdentityFile\s+\K[^\n]+/ms' file


0

Found the solution find . -regex '.*test.*s01e[0-9][0-9].*720p.*x264.*' -exec cp {} /storage/tv/test/s01/ \;


0

GNU findutils uses Emacs style regex, so out of box, this should suffice: find . -regex '.*test.s01e[0-9][0-9]' -exec cp {} /storage/tv/test/s01 \;


2

A BRE doing what you're trying to in sed might look like: sed 's/ *\(\([^ ]*\) *\)\{[num]\}.*/\2/' ...or as an ERE for those seds which support it such as GNU and BSD versions: sed -E 's/ *(([^ ]*) *){[num]}.*/\2/p' ...either expression will begin its match at the first character of the [num]th group (where [num] is a positive integer) of [^ ...


2

In short: \K causes grep to keep everything prior to the \K and not include it in the match. It does not affect what comes after the \K(). This might be enough: " \K(.+)(?= )" Where (?= ) is a non capturing group. or perhaps better: " \K([^ ]+)(?= )" " \K(\w+)(?= )" or similar.


0

You might try this as well . Considering the test directory is in the same directory with other directories , find . -mindepth 2 ! -name test -exec cp {} test \; This will copy all individual files to the directory test , escaping the dir1 , dir2 etc. Note that this will omit subdirectories itself and copies contents of them. you can also test this by ...


2

Try: $ find -type d -name '*dir*' -exec sh -c ' for d do for f in "$d"/*; do [ -f "$f" ] && mv -- "$f" /path/to/test done done ' sh {} +


2

mv "$dir_path"/* ... will not only move files but everything in "$dir_path". At least everything whose name does not start with a dot (hidden files). In bash you can change this with the option dotglob. But if the * expands nicely (matches everything but not too much for a command line) then you can use a shell for indirection: find . -type d -name "*dir*" ...


2

You misunderstand what ack does. It is a grep-analog, not a find-analog. It searches through the contents of files for the given pattern and not for file names matching the pattern. You should instead use find -regex '.*group.*producer.*' Or find -name '*group*producer*' If you insist on using ack (though I see no point in doing so), you can parse ...


1

If grepping over filenames in the current directory is all you need ack matches the contents of files, not their name. To find files whose name matches a regex, run ack over the list of filenames: ls | ack '.*group.*producer.*' What you did, namely ack -n '.*group.*producer.*' will instead look for files in the current directory containing something ...


0

The parts you do not want have a slash and three characters. The part that you want to keep also starts with a slash and have more than three characters, but the third character is an underscore, so we delete all the parts that look like /XXX but not /XX_ This leaves the leading slash on the part that we want to keep, so we finally also delete that one ...


0

sed 's|.*/\([^/]*_[^/]*\)/.*|\1| ' <<\INPUT /ABC/RTE/AD_900_VOP_123/OPP /ABC/RTE/TRE/AD_900_VOP_145/BBB /ABC/RTE/AN_900_VFP_124/FBF /ABC/RTE/HD_900_FOP_153/WEW /ABD/RDV/AD_900_VOP_123/OPP /ABC/RTE/WD_900_VOP_123/GRR/TRD /ABC/RTE/RTD/AR_900_VOP_443/SDD INPUT That will remove up to the second to last occurrence of / immediately preceding a _ ...


1

IMHO Perl offers the easiest and the most flexible solution: perl -nE 'say $1 if m{/(\w+\d+\w+\d+)/};' input_file Please note that input_file is optional: STDIN will be filtered if/when input file name is not given.


1

All answers are good so far, but for this concrete example you can save your time and write a few characters less: sed 's/ & [^ ]*$//' or even better sed 's/ & \S*$//'


1

To remove the last occurrence of a pattern on a line, you can just squeeze it. sed 's/\(.*\)& PID=$!;/\1/' That will match as much as possible in \1 before matching the string so it will always strip only the last occurrence - regardless of whether or not the string you strip is actually at the end of the line. Your attempt: sed 's/\(\& ...


3

sed -e 's/& PID=\$\!;$//' The $ toward the end anchors it to the end of the string.


0

In case Python is an option, you could first memory-map the file and then run an incremental regex search over it, taking advantage of named groups to count pattern occurences. This solution is tolerant of large file sizes from collections import Counter import re, mmap, contextlib c = Counter() with open('data_file', 'r+') as f: with ...


0

find | perl -ne 'print if(m!^\./(\d+)! and $1 > 126 and $1 <363)' ...possibly adding some of the good ideas presented in the other answers. Regex may need some tuning (eg: ^\./(\d+)\w*.po$)


0

sed 's/\./-/' <file name> Without using g at the end of the command you can do this… This will simply replace the 1st occurance of the pattern


3

The fastest solution I can think is flex. Following is an untested skeleton: %{ int count[1000]; %} %% regex0 {count[0]++; } regex1 {count[1]++; } ... .|\n {} %% int main(){ yylex(); // printf the counts; } flex makes a pretty good job in optimizing the automata and generates fast C code. You have to recompile it if regexs change... EDIT: ...


5

Probably awk would be fastest shell tool here. You could try: awk "/$regex1/ { ++r1 } /$regex2/ { ++r2 }"' END { print "regex1:",r1 "\nregex2:",r2 }' <infile Of course if you need to use perl regular expressions like your question, then really perl is the only answer. However, awk does use extended expressions (like grep -E) as opposed to ...


0

sed -n 'y/_E/\t\n/;s/\n/E/;s/[^m]*//;s/\(A.\).*E/\1E/;P' That works for me given your example... miR-16 microRNA ENSG00000206737 miR-378 microRNA ENSG00000222328 If you want the first \tab converted back to a _ then you can add s/\t/_/ before the P - but I think it looks nicer like this. Another way could look like... sed ...


1

Using awk assuming the format is reliable : $ awk -F'_' '{print $5"_"$6, $11}' file miR-16_microRNA ENSG00000206737 miR-378_microRNA ENSG00000222328


2

Using sed: sed 's/^.*\(miR-[0-9]*_microRNA\).*\(ENSG[0-9]*\).*$/\1\t\2/' <infile


4

perl -pe 's!.*(miR-\d+_microRNA).*(ENSG\d+).*!$1\t$2!' explain a bit? Sure, sorry: for each line (perl -p) substitute regex by $1 tab $2 where $1 and $2 are numbered backreferences to capturing groups (...). Nearly all modern regular expression engines support this. about the regular expression: . = any char except \n .* = a sequence of chars ...



Top 50 recent answers are included