Escaped characters from the command-line

J

-j b-

I've run into a bit of an issue that I hope you can help with.
I am working on a parser that allows the user to provide a delimiter as
an argument to the script. However, I can not find a way to [elegantly]
handle escaped characters (such as \t and \n).
A simplified example to illustrate:

# Using
s = ARGV.shift
puts ['west', 'side', story'].join(s)

$ ./parse.rb '\t'
=> west\tside\tstory


Now, I can do something like:

s = ARGV.shift
sep = s =~ /^\\(.)/
when 't'
"\t"
when 'n'
"\n"
# ...
else
s
end
end

$ ./parse.rb '\t'
=> west side story


But I feel that is probably too brittle. I tried Shellwords, but that
didnt seem to help (although I could have been using it incorrectly).
Any suggestions are welcome.
Thanks.
 
A

Albert Schlef

-j b- said:
I am working on a parser that allows the user to provide a delimiter as
an argument to the script. However, I can not find a way to [elegantly]
handle escaped characters (such as \t and \n).
A simplified example to illustrate:

# Using
s = ARGV.shift
puts ['west', 'side', story'].join(s)

$ ./parse.rb '\t'
=> west\tside\tstory

It isn't a Ruby issue. It's a shell one. You need to find out how it's
possible, in your shell, to specify those special characters. Are you
using Linux? Bash?

$ echo one\ntwo
onentwo

$echo 'one\ntwo'
one\ntwo

$echo $'one\ntwo'
one
two

$echo 'one
two'
onw
two

$echo "one
two"
onw
two

So there are at least three ways to do \n in bash.
 
J

-j b-

Albert said:
-j b- said:
I am working on a parser that allows the user to provide a delimiter as
an argument to the script. However, I can not find a way to [elegantly]
handle escaped characters (such as \t and \n).
A simplified example to illustrate:

# Using
s = ARGV.shift
puts ['west', 'side', story'].join(s)

$ ./parse.rb '\t'
=> west\tside\tstory

It isn't a Ruby issue. It's a shell one. You need to find out how it's
possible, in your shell, to specify those special characters. Are you
using Linux? Bash?

Yes. Yes. But the idea is that it shouldnt matter.
So there are at least three ways to do \n in bash.

I know that it possible, from a user standpoint, to input a special
character in multiple ways. My concern is that I dont want to force that
restriction on the user. For example, the utility tr will accept '\t' as
a single character; I find this ultimately more useful than tr '^v[tab]'
' ' (or any of the above mentioned methods).
If it is a shell issue then I am forced to modify the arguments
accordingly. However, I'm still looking for a more elegant way then the
heavy case statement.
I've experimented with a gsub! solution but the way backslashes are
escaped in regular expressions (particularly when reinserting into a
string) has me blocked at the moment.

Thanks.

j
 
A

Albert Schlef

I'm still looking for a more elegant way then the
heavy case statement.
I've experimented with a gsub! solution but the way backslashes are
escaped in regular expressions (particularly when reinserting into a
string) has me blocked at the moment.

All you're looking for is a cool one-liner? Here's one:

s.gsub!(/(\\[ntr])/) { eval %/"#$1"/ }

It replaces any \n and \t sequence by it's character. You can even
enhance the regexp to support \x<number> sequences as well:

s.gsub!(/(\\([ntr]|x\d+))/) { eval %/"#$1"/ }
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- -j b- wrote:

|> It isn't a Ruby issue. It's a shell one. You need to find out how it's
|> possible, in your shell, to specify those special characters. Are you
|> using Linux? Bash?
|
| Yes. Yes. But the idea is that it shouldnt matter.

Have fun rewriting the *NIX shells, cmd.exe, and, possibly, PowerShell, too.

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

Use statement labels that mean something.
~ - The Elements of Programming Style (Kernighan & Plaugher)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgguakACgkQbtAgaoJTgL/PPwCgplzxuF3E608P8jtSCWukpA4o
zlgAn1oQVkLOnSLkmMtwrhMWCGuNro0V
=iHkS
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top