One sed command covers 3 patterns ?
Hi,
I need to write a script to delete the following pattern lines from some files. johnsmith johnsmith, johnsmith: "sed -i /^$username/d $file" doesn't work because users like johnsmith2 will be removed as well. "sed -i /^$username[,:]/d $file" works for the "johnsmith," and "johnsmith:" cases. "sed -i /^$username[$,:]/d $file" and "sed -i /^$username[\n,:]/d $file" don't work. The "johnsmith" line cannot be removed. How can I use one sed command (or something else) to cover all these 3 cases? Thank you in advance! |
sed will honour "|" (or) as well as "$" as an anchor.
|
Use the question mark. It's a wild multiplier that means once or not at all. Also there is a code for punctuation marks as a class. Look it up. You already seem to know enough about regular expressions to combine these two notations to give you what you want.
|
Quote:
Code:
sed -i -e '/^johnsmith[[:punct:]]$/d' -e '/^johnsmith$/d' |
And in case you haven't guessed, there just might be a few ways of achieving your desired outcome.
How like linux ... :p |
\| and \? are GNU extensions.
The latter is short for the more universal \{0,1\} Here it must be followed by $ to ensure it's at the end of the line. The [ ] should be within quotes to ensure the shell does not try a glob. Best have all sed code in quotes. Code:
sed -i "/^$username[,:]\{0,1\}$/d" $file |
Hi, Thank you very much all for your prompt replies that are very helpful !!
This compact one works very well: sed -i "/^$username[[:punct:]]\{0,1\}$/d" $file The only case that it can't do is "johnsmith ,". Any idea? |
This one is really good "sed -i "/^$username[,:]\{0,1\}$/d" $file". Thanks MadeInGermany !
|
Ooh simileys. Please wrap your code in code tags (=> the # button at the top of the Wiki editor).
Quote:
Code:
sed -i "/^$username[[:space:]]*[[:punct:]]\{0,1\}$/d" $file the [[:space:]] is a class of space characters (including Space, TAB, CR, vertical TAB). There is also [[:blank:]] that is only a space or TAB character. Followed by a * means it can occur zero or once or many times. |
Hi,
A similar question: How to make the following line shorter, or put the three grep to one? if grep -q ^$username$ $file || grep -q ^$username, $file || grep -q ^$username: $file ; then Thanks. |
Thank you much again MadeInGermany !
|
The same RE applies for grep (but no / / that in sed delimits the RE from other code):
Code:
if grep -q "^$username[:,]\{0,1\}$" $file; then Code:
if grep -q "^$username[[:punct:]]\{0,1\}$" $file; then Code:
if grep -q "^$username[[:blank:]]*[:,]\{0,1\}$" $file; then |
Thanks MadeInGermany! Glad to know this good format working for grep as well.
Sorry for my mistake. I failed to make it clearer. Actually the patterns to remove are johnsmith johnsmith,John Smith... johnsmith:John Smith... So the following code doesn't fulfill the requests perfectly: Code:
sed -i "/^$username[[:punct:]]\{0,1\}$/d" $file |
Quote:
The "$" means "end-of-line". Therefore, "johnsmith,John Smith" won't match "johnsmith$", will it? The solution I gave you in post #4 can easily be modified to include the references about blank spaces as well. You should experiment and find your solution, since all the pieces have already been given to you. |
This can be handled by a \( \) group marker. A following quantifier handles the whole group.
Code:
sed -i "/^$username\([,:].*\)\{0,1\}$/d" $file Code:
sed -r -i "/^$username([,:].*){0,1}$/d"$file Code:
sed -r -i "/^$username([,:].*)?$/d" $file Code:
sed -i "/^$username$/d; /^$username[,:].*$/d" file |
All times are GMT -5. The time now is 09:25 PM. |