LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-04-2011, 09:19 PM   #1
otkaz
LQ Newbie
 
Registered: Apr 2009
Location: Houston, TX
Posts: 26

Rep: Reputation: 0
bash substitution on apostrophes help


Hi I'm having a problem with part of a script where I clean a variable of certain chars by adding an escape \ to the beginning of them.
Example
Code:
FILENAME="${FILENAME//[/\[}"
FILENAME="${FILENAME//]/\]}"
FILENAME="${FILENAME//(/\(}"
FILENAME="${FILENAME//)/\)}"
FILENAME="${FILENAME//&/\&}"
FILENAME="${FILENAME// /\ }"
got stuck on ' apostrophes
this does not work
Code:
FILENAME="${FILENAME//'/\'}"
recognises them as syntax
./testscript.sh: eval: line 6: unexpected EOF while looking for matching `''
./testscript.sh: eval: line 7: syntax error: unexpected end of file
Sorry I'm sure this is pretty basic stuff I should be able to get on my own, but I'm really stuck any help is greatly appreciated.
 
Old 10-04-2011, 10:01 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Quote:
Originally Posted by otkaz View Post
Hi I'm having a problem with part of a script where I clean a variable of certain chars by adding an escape \ to the beginning of them.
Example
Code:
FILENAME="${FILENAME//[/\[}"
FILENAME="${FILENAME//]/\]}"
FILENAME="${FILENAME//(/\(}"
FILENAME="${FILENAME//)/\)}"
FILENAME="${FILENAME//&/\&}"
FILENAME="${FILENAME// /\ }"
got stuck on ' apostrophes
this does not work
Code:
FILENAME="${FILENAME//'/\'}"
recognises them as syntax
./testscript.sh: eval: line 6: unexpected EOF while looking for matching `''
./testscript.sh: eval: line 7: syntax error: unexpected end of file
Sorry I'm sure this is pretty basic stuff I should be able to get on my own, but I'm really stuck any help is greatly appreciated.
Code:
echo $FILENAME 
huh'hah
FILENAME="${FILENAME//\'/\'}"
echo $FILENAME 
huh\'hah
That what you're after?

Last edited by Tinkster; 10-04-2011 at 10:05 PM.
 
Old 10-04-2011, 10:22 PM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
The field inside the parameter substitution is considered a separate quoting environment from the main line, so quotes, the backslash itself, and a couple of other characters need to be individually escaped.
Code:
FILENAME="${FILENAME//\'/\'}"
FILENAME="${FILENAME//\"/\\\"}"
It may seem odd that for the single quote, the replacement string needs to be kept literal, but for the double quote the backslash needs to be escaped as well.

I believe this is due to the whole line being parsed after the substitution is made, where the outer double-quotes protect the single quotes in the variable string , but not the doubles. \" and \\ are parsed inside double quotes, but \' is not.

See, and carefully read, the QUOTING section of the bash man page for more details on this.
 
Old 10-04-2011, 11:51 PM   #4
otkaz
LQ Newbie
 
Registered: Apr 2009
Location: Houston, TX
Posts: 26

Original Poster
Rep: Reputation: 0
using FILENAME="${FILENAME//\'/\'}" instead of FILENAME="${FILENAME//'/\'}" did the trick. I would have probably never figured this out on my own thanks guys!
 
Old 10-05-2011, 04:41 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
My question would be around what is the point of replacing an apostrophe with itself?
 
Old 10-05-2011, 08:22 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Quote:
Originally Posted by grail View Post
My question would be around what is the point of replacing an apostrophe with itself?
It's not. It's replacing the apostrophe with a backslashed apostrophe. The replacement string outputs literally. Try it out.

It appears to work similarly to sed substitutions. The LHS needs to strictly parse escapes, but the RHS does not. The only backslash interpretation that occurs on the substituted string comes after the parameter has been expanded, as I pointed out before.
 
Old 10-06-2011, 12:38 AM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I must be missing something then:
Code:
$ x="one'two"
$ echo $x
one'two
$ echo ${x//\'/\'}
one'two
So I would consider this tried out and not what has been advertised

Code:
$ bash --version
GNU bash, version 4.2.10(1)-release (x86_64-unknown-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
Old 10-06-2011, 01:14 AM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
You didn't quote the variable, so the backslash was subsequently removed again after the expansion.

The behavior of backslashes is different inside double quotes than when unquoted. Whereas all escapes are processed in unquoted strings, soft quotes only reduce \$, \`, \", \\, and \<newline> into their literal equivalents, along with certain escape sequences like \n. All other combinations are retained as-is.
 
Old 10-06-2011, 02:26 AM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
@David - thank you for the clarity ... my bad on forgetting to quote

So what about replacing say one of the letters in the line with an apostrophe and still having the variable quoted?
Code:
$ x="one'two"
$ echo $x
one'two
$ echo "${x//e/\'}"
on\''two
$ echo "${x//e/'}"
>
# desired output
on''two
 
Old 10-06-2011, 10:44 AM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Wow, that is a tricky one. I honestly can't see any direct way to accomplish it. It looks like you may have discovered a genuine weakness in the syntax.

Quoting and backslashing doesn't work, obviously, and I even tried this, with no success:
Code:
$ echo "${x//e/$'\047'}"
bash: bad substitution: no closing `}' in "${x//e/'}"
But this does work, probably because the ascii conversion takes place after the substitution:
Code:
$ x="one'two"
$ echo -e "${x//e/\047}"
on''two
This works too:

Code:
$ y="'"
$ echo "${x//e/$y}"
on''two
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash - find - substitution Berni314 Programming 13 09-19-2011 08:41 AM
[SOLVED] Bash string substitution porphyry5 Programming 1 05-14-2011 01:08 AM
[SOLVED] bash variable substitution Jerry Mcguire Programming 6 04-29-2010 09:33 AM
Bash Command Substitution dakensta Programming 5 11-30-2006 03:10 PM
Bash Process Substitution joshholt Programming 4 10-11-2005 03:15 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:34 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration