Results 1 to 10 of 10
Hello Everyone,
I need to read an encrypted password from the user and update that value in an xml file. I am trying to use "sed" for searching the appropriate ...
- 02-02-2012 #1Just Joined!
- Join Date
- Feb 2012
- Posts
- 3
Need help with sed to escape special characters
Hello Everyone,
I need to read an encrypted password from the user and update that value in an xml file. I am trying to use "sed" for searching the appropriate tag and replacing this new value that get from the user. Since the encrypted password can contain special characters(like /,\,&,etc), the "sed" command is coming garbled. Could somebody please help to find an efficient solution for this problem?
Is there a way to instruct sed command not to consider any special characters in the replacement string?
Something like s/${key}/"what ever string"/
Or
Any efficient way to put escape sequence for the special characters?
I tried something like 's/\|/\\|/g' , 's|\\|\\\\|g' to escape individual special characters. But this is not working for special characters like &,/ etc.... Is it possible to write any generic pattern which can handle any special characters.
Very much appreciate any help
Thanks,
Martin
- 02-02-2012 #2Just Joined!
- Join Date
- Aug 2011
- Posts
- 48
This worked for me
Code:$ cat runScript #!/bin/bash # Some crazy string value str="$%^()|||@" # In-place replace sed -ie 's/'"$str"'/whatever/' file $ cat file this is test to see if $%^()|||@ get replaced. $ ./runScript $ cat file this is test to see if whatever get replaced.
- 02-03-2012 #3Just Joined!
- Join Date
- Feb 2012
- Posts
- 3
Thank you so much for spending time on my post.
But I faced the problem mainly with /, \, and & when used inside the replacement string. With your solution also it's failing for any of these characters.
Each of these characters has a different meaning in the sed context,
1) "/" is used as the delimiter,
2) "\" will escape the character preceding it, even the actual delimiter if \ is the last character in the search/replacement pattern,
3) & is used to remember the matched string
Thanks,
Martin
- 02-03-2012 #4Just Joined!
- Join Date
- Aug 2011
- Posts
- 48
I'm getting close with
Beware of the difference between "" and ''. Like in my example if I use " " for the instead of ' ' the variable \ is lost.Code:#!/bin/bash str='/\$%^&/&()|||@' echo $str str=${str//\\/\\\\} str=${str//\//\\/} #str=${str//&/\\&} #str=${str//|/\\|} echo $str sed -ie 's/'"$str"'/whatever/' file $ cat file this is test to see if /\$%^&/&()|||@ get replaced. $ ./runScript /\$%^&/&()|||@ \/\\$%^&\/&()|||@ $ cat file this is test to see if whatever get replaced. $
And I'm not escaping the & or | because this is working without them for me.
So the question is, when you "read an encrypted password from the user" will the \ be suppressed in the string?
Thoughts.
- 02-03-2012 #5Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Hi.
Here is a minimal perl script to ignore special characteristics of characters in a source string. The script s5 uses the perl script p5:
producing:Code:#!/usr/bin/env bash # @(#) s5 Demonstrate string replacement, ignore RE, perl. # Utility functions: print-as-echo, print-line-with-visual-space, debug. # export PATH="/usr/local/bin:/usr/bin:/bin" pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; } db() { : ; } C=$HOME/bin/context && [ -f $C ] && $C perl FILE=${1-data1} pl " Input data file $FILE:" cat $FILE pl " Minimalist perl script:" cat p5 pl " Results:" ./p5 '!@#$%^&*()_+=-[]{}:".,<>\|' 'Hello, world' $FILE exit 0
The various man pages related to perl and perldoc, e.g. perldoc -f substr, provide details. (This script was adapted from one that did more checking of arguments, etc.)Code:% ./s5 Environment: LC_ALL = C, LANG = C (Versions displayed with local utility "version") OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64 Distribution : Debian GNU/Linux 5.0.8 (lenny) GNU bash 3.2.39 perl 5.10.0 ----- Input data file data1: What a nice spring day ! This string: !@#$%^&*()_+=-[]{}:".,<>\| will be replaced. Now is the time for all good men to come to the aid of their country. ----- Minimalist perl script: #!/usr/bin/env perl # @(#) p5 Demonstrate string replacement, ignore RE metas (minimal). use strict; use warnings; my ( $old, $new, $global, $line, $debug, $t1, $t2 ); $old = shift; $new = shift; $global = 0; $debug = 0; while (<>) { chomp( $line = $_ ); print " Replacing :$old: with :$new:\n" if $debug; while ( ( $t1 = index( $line, $old ) ) >= 0 ) { print " Starting position of :$old: in :$line: is $t1\n" if $debug; $t2 = length($old); print " Length of :$old: is $t2\n" if $debug; substr( $line, $t1, $t2, $new ); last if not $global; } print "$line\n"; } exit(0); ----- Results: What a nice spring day ! This string: Hello, world will be replaced. Now is the time for all good men to come to the aid of their country.
Best wishes ... cheers, drlWelcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )
- 02-03-2012 #6Just Joined!
- Join Date
- Aug 2011
- Posts
- 48
So you have to do it as a string and not use a regex?
- 02-04-2012 #7Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )
- 02-05-2012 #8Just Joined!
- Join Date
- Aug 2011
- Posts
- 48
Is a string operation.$t1 = index( $line, $old )
I was thinking of something like
Code:perl -pi -e 's/SomeCrazyEscapeSequence/cat/' userfile
- 02-05-2012 #9Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Hi.
If SomeCrazyEscapeSequence has no RE metacharacters in it or are all escaped, then what does it become?
Best wishes ... cheers, drlCode:The simplest regex is simply a word, or more generally, a string of characters. ... Not all characters can be used 'as is' in a match. Some characters, called metacharacters, are reserved for use in regex notation. The metacharacters are {}[]()^$.|*+?\ A metacharacter can be matched by putting a backslash before it ... Search and replace is performed using "s/regex/replacement/modifiers". -- excerpts from man perlrequickWelcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )
- 02-08-2012 #10Just Joined!
- Join Date
- Feb 2012
- Posts
- 3
Thanks a ton histrungalot and drl for the wonderful solutions.
I could not use the perl script as I do not have much exposure to perl.
Here is the script that finally worked for me,
##############################################
read -r password
password=${password//\\/\\\\}
password=${password//|/\\|}
#password=${password/\|/\\|}
password=${password//&/\\&}
quote='"'
password_xml="${password_xml} password=${quote}${password}${quote}"
password_xml="${password_xml}/>"
${SED} 's|<PASS_TAG.*>|'"$password_xml"'|' ${CONFIG_XML} > ${CCONFIG_XML}.$$
/bin/mv -f ${CONFIG_XML}.$$ ${CONFIG_XML}
################################################## ########
Thanks again for your kind help.
Thanks,
Martin


Reply With Quote
