Tag Info

New answers tagged

3

You can't use capture groups from the regexp in the command to execute. If you use find -regex to restrict matches, you'll have to do some extra matching in the command. You can do that by invoking a shell and using its own pattern matching constructs. For example, if foo and bar are constant strings and regex1 can't match bar: find … -exec sh -c ' ...


2

^=* means search for a line starting with zero or more equal signs. If you want lines starting with = just use ^=


1

Just use awk (using grep seems redundant to me, since awk already can match a regular expression): awk '$0~/\s*\#define\s*\[.*\]\s*.*/ {print $3}' *.h Going through the expression in more detail: $0 ~ /regexp/ # look for the regular expression in the record \s* # whitespace, any number of times \#define # literal ...


1

Use grep -o to print only the matching part of the line. Obviously take the \s part out again, because you don't want that part.


2

How about: tr '|' '\n' | sed -n 's/=Y$//p'


1

perl -nE 'say join(",",/(\w+)=Y/g)'


2

awk can read records based on a regex delimiter of your choice. eg '[|\n]' It can also split records into fields on the delimeter of your choice. eg. '=' The ternary operator (condition)?: prevents a leading comma. awk -F= -vRS='[|\n]' '$2=="Y"{ printf (i?",":"")"%s", $1; i=1 }' output: p2,p6 If a trailing newline is needed, it can be appended in ...


6

Using Perl compatible regular expression in grep: grep -Po '..(?==Y)' <file Result: p2 p6


1

a simple awk awk -F\| '{for (i=1 ; i<= NF; i++) if ( $i ~/Y/ ) { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;}}' where -F\| use | as separator {for (i=1 ; i<= NF; i++) scan through pattern if ( $i ~/Y/ ) if found { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;} split it and print it output in 3 : p2 in 11 : p6 use printf ...


3

Try this: echo 'p1=X||p2=Y||p3=X||p4=X||p5=X||p6=Y||p7=X' | grep -o '[^|]*=Y' | cut -d= -f1 | sed -e 'N;s/\n/,/g' Output: p2,p6


2

sed -e "s/^-\([0-9][0-9][0-9][0-9]\)/\1-/" file.csv The part between \( and \) is referenced in the replacement part by \1, allowing to replace by "whatever matched the search". Note that if you are using a csv file, this will only work if the column is really the first one (^ matches the beginning of the line). If the column is somewhere else, you might ...


0

Maybe this is what you need: #!usr/bin/perl use strict; use warnings; my@list=qw(2 7 8 9 11 15 34 91 91 92 94); my%hash; print "Input:\n@list\n"; foreach(@list) { #count occurences for each element ...


1

There are several implementations of locate, and the ones I'm aware of want either POSIX extended regexps, or POSIX basic regexps. Neither support lookaheads.


2

sed 's/=\([^= ]*\) *$/(\1)&/' <in >out The above will just replace the last equals sign on a line and all characters which follow first with... A copy of those that follow and which are not space surrounded by two parens (in case there are any trailing spaces on a line) The whole matched pattern all over again. On the right-hand-side (the ...


2

Suppose all the data is there in a file named as file, then awk -F "=" '{print $1"("$2")="$2}' file


3

Use that: sed 's/=\(+[0-9]\+\)/(\1)=\1/' file It searches for =+ followed by at least one digit ([0-9]\+) and replaces all with the desired format ((\1)=\1).


7

sed 's/=\(+[0-9]\{1,3\}\)/(\1)=\1/' To address your problem (as I understood): Patterns that need to be memorized in sed are to be enclosed in parentheses - their appearance defines their index number. E.g.: sed 's/\(<memorized_pattern_1>\)<not_memorized>\(<memorized_pattern_2>\)/\2\1/' would swap patterns 1 and 2 and delete the ...


0

Use a zero-width positive look-ahead assertion: perl -pe 's/^(?=.)/\section{}/' perlre says: (?=pattern) A zero-width positive look-ahead assertion. For example, /\w+(?=\t)/ matches a word followed by a tab, without including the tab in $& Another solution: perl -lpe 's/^/\section{}/ if length' You should chomp \n at the end of a line before ...


1

You can use awk and set the field separator to either spaces or comma. Then, loop in blocks of 2, printing the first and second fields together with blocks of two: $ awk -v FS='(\\s+|,)' '{for (i=3; i<=NF; i+=2) print $1, $2, $i, $(i+1)}' file 3923 001 L05 LV 3923 001 L05 RM 3923 002 L12 RA 3923 002 L12 LA 3923 003 I06 ALL 3923 004 G04 RV 3923 004 Z09 ...


1

Simplyfied variant of User112638726 answer sed ':1;s/\(\(.*\s\s\+\)[^,]\+\),/\1\n\2/;t1' sed -r ':1;s/((.+\s\s+)[^,]+),/\1\n\2/;t1' will choice repeated part as «any symbols before 2(or more) spaces». Then you can pipe output through uniq -s 10


6

Given the format of your example this should work for any number of comma separated strings after the initial large space(if it's a tab just change the spaces in the second s/// to \t sed ':;h;s/,.*//;p;x;s/ [^,]*,/ /;t;d' file 3923 001 L05 LV 3923 001 L05 RM 3923 002 L12 RA 3923 002 L12 LA 3923 003 I06 ALL 3923 004 G04 RV 3923 ...


2

Possible solution with awk: awk -F" " '{ x = $3 " " $4 " " $5; split(x, a, ","); for (i in a) { print $1, $2 "\t" a[i]; } }' file Output should be: 3923 001 L05 LV 3923 001 L05 RM 3923 002 L12 RA 3923 002 L12 LA 3923 003 I06 ALL 3923 004 G04 RV 3923 004 Z09 ALL And if your input contains multiple , as in comments: 3923 001 L05 ...


3

It is possible using sed. Pipe the input to the below. | sed 's/\(^.\{12\}\)\([^,]\+\),\([^,]\+\)/\1\2\n\1\3/' output 3923 001 L05 LV 3923 001 L05 RM 3923 002 L12 RA 3923 002 L12 LA 3923 003 I06 ALL 3923 004 G04 RV 3923 004 Z09 ALL Here is the source to handle input with multiple "," For original input without tab, use | perl ...


0

BRE syntax is non-elegant where some other variations are elegant because BRE is designed to be easily abstracted. BRE is simply parsed - a programmer implementing his/her own BRE-based grammar subset need never worry if the match string \s is meant to indicate a \backslash followed by an s or the [[:space:]] character class - because the former is always ...


2

Let's do this using a simple example, consider for a file, we will replace each digit of a line with the string HELLO, if the line does not have any digit then leave it as it is : #!/usr/bin/env python2 import re with open('file.txt') as f: for line in f: if re.search(r'\d', line): print re.sub(r'\d', 'HELLO', line).rstrip('\n') ...


4

Just for fun: python -c 'import sys,fileinput,re;sys.stdout.writelines(re.sub("stuff", "changed", l, 1) for l in fileinput.input() if re.search("patternmatch", l))' file Don't do it:) Use sed/perl/awk


8

Use the modifier form of if: perl -ne 's/stuff/changed/, print if /patternmatch/' or, you can use and and or for flow control: perl -ne '/patternmatch/ and s/stuff/changed/, print'


1

I had access logs where the dates where stupidly formatted : [30/Jun/2013:08:00:45 +0200] but I needed to display it as : 30/Jun/2013 08:00:45 The problem is that using "OR" in my grep statement, I was receiving the 2 match expressions on 2 separated lines. Here is the solution : grep -in myURL_of_interest *access.log | \ grep -Eo ...


1

According to the GNU Grep documentation: If the final byte of an input file is not a newline, grep silently supplies one. So, if you're using GNU grep, you should be able to use the beginning-of-line/end-of-line anchors (^ and $) as usual, even if you're not working on properly-formed plaintext files. grep '^.\{32\}$' fileA fileB


5

This works. ^ denotes start of line, plus the {32} you already had, then a $ for end of line. $ cat fileA fileB 12345678901234567890123456789012 123456789012345678901234567890123 12345678901234567890123456789012 123456789012345678901234567890124 $ grep -E "^.{32}$" fileA fileB fileA:12345678901234567890123456789012 fileB:12345678901234567890123456789012 $ ...


0

^Addr does match Addr at the beginning of a line. The character ^ only means “not” when it's at the beginning of a character class, e.g. [^abc] means “any one character that isn't a, b or c”. I think your problem is that you're using the command %g, which matches files by their content, but you meant to use %m, which matches files by their name. %m ^Addr ...


1

Simply: rm -rf /root/my-picture-2015-*/


0

If you are inside the root directory, then you can use this command to delete the required folders: find -type d -maxdepth 1 -iregex ".*my-picture-[0-9]*-[0-9]" -exec rm -r {} + Here, -maxdepth ==> do no descend beyond the first level for searching


0

In Emacs, I sometimes use this regex: ^J\([^^J]\) -> \1 Means: replace every newline that is followed by something which is NOT a newline with only the thing, that followed the newline That way I get rid of all newlines within a paragraph but keep paragraphs (double-newlines)


1

You could use extended globbing if your shell supports it, e.g. bash: shopt -s extglob for f in NA*([[:alnum:]]).txt; do something; done zsh: setopt extendedglob for f in NA([[:alnum:]])#.txt; do something; done where *(...) and respectively (...)# mean zero or more occurrences.


1

for f in ./* do case ${f#??} in (*.*.*|*[!-_.[:alnum:]]*) ;; (NA*.txt) : do something w/ "$f" esac done The case statement allows you to branch code blocks for multiple possibilities. Though I make the above match for 2 or more dots or a not-dash-underscore-dot-alphanumeric character a no-op, you're just as free to put a ...


0

egrep should do: egrep 'NA[A-Z a-z 0-9]*\..{3,4}$' So ls /path/to/dir | egrep 'NA[A-Z a-z 0-9]*\..{3,4}$' would list: NAfoo.txt NAbar1.jpeg NA123baz.txt but would exclude: aiNA1foo.txt NA2foo_bar.jpeg NAbar.baz.txt And so on.


3

The code below will allow you to perform some action on text files starting with "NA", only having alphanumeric characters, and ending in ".txt". for f in /path/to/your/folder/*; do if [[ ${f##*/} =~ NA[a-zA-Z0-9]*.txt ]]; then # perform some action on $f fi done If you want to allow your file to start with "N" or "A" use this: for f in ...


1

Here a fast hack: #!/bin/bash for i in *; do if [ $(echo $i|cut -c 1-2) == "NA" ]; then EXECUTE_COMMAND fi done Did I understand your question correct?


3

One option is to search with prefixed spaces, such as: / alias, where there are two spaces before the word "alias" to prevent false positive matches where "alias" appears as part of another sentence. You can also ground the match to the beginning of the line if you know exactly how many spaces there are: /^ alias for example. However your expressions ...


4

You can do it like this: sed -e's/ \([^ ][^ ]\)/\n\1/g' \ -e's/\([^ ][^ ]\) /\1\n/g' \ -e's/ //g;y/\n/ / ' <<\IN I have a source text file containing text where some words are l e t t e r s p a c e d like the word "letterspaced" in this question (i.e., there is a space character between the letters of the word. IN The idea ...


3

A Perl approach that mostly works: perl -C -lpe 's/(?:^|\P{L})\K\p{L}(?:\s\p{L})+(?=\P{L}|$)/$&=~s{\s}{}rgo/goe' This assumes a version of Perl recent enough to know about the /r flag in replacements. Proof of concept: $ echo 'Do I like «ł é t t ê r s p ä c è đ» text?' | perl -C -lpe ...


0

Perl's lookahead assertions make this simple. AFAIK, sed lacks these. Given that two or more whitespaces separate the words, this eliminates single spaces but leaves unaltered sequences of two or more: perl -pe 's/\s(?!\s)//g' myfile The p switch causes Perl to read myfile and then substitute single spaces (\s) which are NOT followed by another space. ...


1

With sed: sed -e '$!N;/\n<name>/s/\n//' file If all your lines are in a sequence, you can use paste: paste -sd'\0\n' file


0

I temporarily replaced my .forward file with yours and confirmed that it doesn't work. There are two problems. contains performs a substring match, and does no understand regular expressions. For regexes you want matches rather than contains. The \d PCRE-style character class appears to be broken as does the {N} syntax! I tried all kinds of combinations. ...



Top 50 recent answers are included