unterminated `s' command, can't find my mistake - regex

sudo wbinfo --group-info GROUPNAME| sed -r -e 's/(?:DOMAIN\\(\w+),?)|(?:[^]+:)/$1/g'
This command results in an
sed: -e expression #1, char 36: unterminated `s' command
The output of
sudo wbinfo --group-info GROUPNAME
is like
GROUPNAME:x:0123456789:DOMAIN\user1,DOMAIN\user2,DOMAIN\user3,...,DOMAIN\userN
I tried escaping all instances of ( with \(, \ with \\ (also \\ with \\\\)
sudo wbinfo --group-info GROUPNAME| sed -r -e s/'(?:DOMAIN\\(\w+),?)|(?:[^]+:)'/$1/g
(changed quoted area)
sudo wbinfo --group-info GROUPNAME| sed -r -e s/'(?:DOMAIN\\(\w+),?)|(?:[^]+:)/\1/g'
(\1 instead of $1)
I still don't know how to get what I need:
user1 user2 user3 ... userN

TL;TR
Your attempt is too complicated, you can simply use this:
sed -r 's/[^\]+DOMAIN\\([[:alnum:]]+)/\1 /g'
About the syntax error:
You are using sed -r which enables extended posix regular expressions. Note that in extended posix regular expressions the ? is used as a quantifier for optional repetition. You you need to escape it:
sed -r -e 's/(\?:DOMAIN\\(\w+),\?)|(\?:[^]+:)/$1/g'
However, there is still a problem left with the regex: you are using [^]. Note that the ^ when used in a character class, negates the match of that class. You are using the ^ but missed to say which characters should not matched. You need to put in something like:
sed -r -e 's/(\?:DOMAIN\\(\w+),\?)|(\?:[^abc]+:)/$1/g'

awk to the rescue!
$ ... | awk -F'\\\\' -v RS=, '{print $2}'
will give the result one user per line, if you want them to appear on a single line add ... | xargs

Here's another approach with sed:
sed -r -e 's/^.*://' -e 's/[^,]+\\//g' -e 's/,/ /g'
First remove all the stuff before the last colon in the line,
then remove all the domain parts (non-commas followed by a backslash),
then change commas to spaces.

Related

Delete any special character using Sed

I have yet another list of subdomain. I want to remove any Wildcard subdomain which include these special characters:
()!&$#*+?
Mostly, the data are prefixly random. Also, could be middle. Here's some sample of output data
(www.imgur.com
***************diet.blogspot.com
*-1.gbc.criteo.com
------------------------------------------------------------i.imgur.com
This has been quite an inconvenience while scanning through the list. As always, I'm trying sed to fix it:
sed -i "/[!()#$&?+]/d" foo.txt ###Didn't work
sed -i "/[\!\(\)\#\$\&\?\+]/d" ###Escaping char didn't work
Performing commands above still result in an unchanged list and the file still on original state. I'm thinking that; to fix this is to pipe series of sed command in order to remove it one by one:
cat foo.txt | sed -e "/!/d" -e "/#/d" -e "/\*/d" -e "/\$/d" -e "/(/d" -e "/)/d" -e "/+/d" -e "/\'/d" -e "/&/d" >> foo2.txt
cat foo.txt | sed -e "/\!/d" | sed -e "/\#/d" | sed -e "/\*/d" | sed -e "/\$/d" | sed -e "/\+/d" | sed -e "/\'/d" | sed -e "/\&/d" >> foo2.txt
If escaping all special char doesn't work, it must've been my false logic. Also tried with /g still doesn't increase my luck.
As a side note: I don't want - to be deleted as some valid subdomain can have - character:
line-apps.com
line-apps-beta.com
line-apps-rc.com
line-apps-dev.com
Any help would be cherished.
Using sed
$ sed '/[[:punct:]]/d' input_file
This should delete all lines with special characters, however, it would help if you provided sample data.
To do what you're trying to do in your answer (which adds [ and ] and more to the set of characters in your question) would be:
sed '/[][!?+,#$&*() ]/d'
or just:
grep -v '[][!?+,#$&*() ]'
Per POSIX to include ] in a bracket expression it must be the first character otherwise it indicates the end of the bracket expression.
Consider printing lines you want instead of deleting lines you do not want, though, e.g.:
grep '^[[:alnum:]_.-]$' file
to print lines that only contain letters, numbers, underscores, dashes, and/or periods.

Why does this regex work in grep but not sed?

I have two regular expressions:
$ grep -E '\-\- .*$' *.sql
$ sed -E '\-\- .*$' *.sql
(I am trying to grep lines in sql files that have comments and remove lines in sql files that have comments)
The grep command works using this regex; however, the sed returns the following error:
sed: -e expression #1, char 7: unterminated address regex
What am I doing incorrectly with sed?
(The space after the two hyphens is required for sql comments if you are unfamiliar with MySql comments of this type)
You're trying to use:
sed -E '\-\- .*$' *.sql
Here sed command is not correct because you're not really telling sed to do something.
It should be:
sed -n '/-- /p' *.sql
and equivalent grep would be:
grep -- '-- ' *.sql
or even better with a fixed string search:
grep -F -- '-- ' *.sql
Using -- to separate pattern and arguments in grep command.
There is no need to escape - in a regex if it is outside bracket expression (or character class) i.e. [...].
Based on comments below it seems OP's intent is to remove commented section in all *.sql files that start with 2 hyphens.
You may use this sed for that:
sed -i 's/-- .*//g' *.sql
The problem here is not the regex, the problem is that sed requires a command. The equivalent of your grep would be:
sed -n '/\-\- .*$/p'
You suppress output for non-matching lines -n ... you search (wrap your regex in slashes) and you print p (after the last slash).
P.S.: As Anub pointed out, escaping the hyphens - inside the regex is unnecessary.
You are trying to use sed's \cregexpc syntax where with \-<...> you are telling sed the delimiter character you want use is a dash -, but you didn't terminate it where it should be: \-<...>- also add d command to delete those lines.
sed '\-\-\-.*$-d' infile
see man sed about that:
\cregexpc
Match lines matching the regular expression regexp. The c may be any character.
if default / was used this was not required so:
sed '/--.*$/d' infile
or simply:
sed '/^--/d' infile
and more accurately:
sed '/^[[:blank:]]*--/d' infile

How to ignore word delimiters in sed

So I have a bash script which is working perfectly except for one issue with sed.
full=$(echo $full | sed -e 's/\b'$first'\b/ /' -e 's/ / /g')
This would work great except there are instances where the variable $first is preceeded immediately by a period, not a blank space. In those instances, I do not want the variable removed.
Example:
full="apple.orange orange.banana apple.banana banana";first="banana"
full=$(echo $full | sed -e 's/\b'$first'\b/ /' -e 's/ / /g')
echo $first $full;
I want to only remove the whole word banana, and not make any change to orange.banana or apple.banana, so how can I get sed to ignore the dot as a delimiter?
You want "banana" that is preceded by beginning-of-string or a space, and followed by a space or end-of-string
$ sed -r 's/(^|[[:blank:]])'"$first"'([[:blank:]]|$)/ /g' <<< "$full"
apple.orange orange.banana apple.banana
Note the use of -r option (for bsd sed, use -E) that enables extended regular expressions -- allow us to omit a lot of backslashes.

sed plus sign doesn't work

I'm trying to replace /./ or /././ or /./././ to / only in bash script. I've managed to create regex for sed but it doesn't work.
variable="something/./././"
variable=$(echo $variable | sed "s/\/(\.\/)+/\//g")
echo $variable # this should output "something/"
When I tried to replace only /./ substring it worked with regex in sed \/\.\/. Does sed regex requires more flags to use multiplication of substring with + or *?
Use -r option to make sed to use extended regular expression:
$ variable="something/./././"
$ echo $variable | sed -r "s/\/(\.\/)+/\//g"
something/
Any sed:
sed 's|/\(\./\)\{1,\}|/|g'
But a + or \{1,\} would not even be required in this case, a * would do nicely, so
sed 's|/\(\./\)*|/|g'
should suffice
Two things to make it simple:
$ variable="something/./././"
$ sed -r 's#(\./){1,}##' <<< "$variable"
something/
Use {1,} to indicate one or more patterns. You won't need g with this.
Use different delimiterers # in above case to make it readable
+ is ERE so you need to enable -E or -r option to use it
You can also do this with bash's built-in parameter substitution. This doesn't require sed, which doesn't accept -r on a Mac under OS X:
variable="something/./././"
a=${variable/\/*/}/ # Remove slash and everything after it, then re-apply slash afterwards
echo $a
something/
See here for explanation and other examples.

using sed command in substitution

When I use this command
echo jones:Adrian W. Jones/OSD211/555-0123 | sed -e 's=^([^:]*):[^/]*/([^/]*)/.*$=\1:\2='
I got: sed: command garbled: s=^([^:]):[^/]/([^/])/.$=\1:\2=
but when I use this one:
echo jones:Adrian W. Jones/OSD211/555-0123 | sed -e 's=^\([^:]*\):[^/]*/\([^/]*\)/.*$=\1:\2='
I got: jones:OSD211
Why should I escape the ( in sed?
by default, sed uses BRE. in BRE, ( is literal (, you have to escape it to bring it special meaning (grouping)
p.s. Gnu sed has -r option to enable ERE.