9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] rc scripts, how to get spaces in array elements generated by command output?
@ 2019-01-05 21:13 Mack Wallace
  2019-01-05 23:52 ` Anthony Martin
  0 siblings, 1 reply; 4+ messages in thread
From: Mack Wallace @ 2019-01-05 21:13 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 3012 bytes --]

I apologize if this is not the correct forum for this question. However, since I am trying to write a script in Plan 9’s rc shell, this seemed to be the best place to go - as most scripting resources are based on bash, and I could not find the answer in the rc references I could find. - and I’m rather new to scripting in general as it is.

My question: Is there a way to take the string output of a command that contains spaces and make it a single element of an array in rc script?

For example:

If I declare an array and output its contents with the following script:

declared_array = (‘hello world’ ‘good luck’)
echo $declared_array(1) 
echo $declared_array(2)

I will get:

hello world
good luck
 

However, if I am receiving output from sed that contains spaces from the following script line

string_var = `{echo some_string | sed ’s/x/y/g’}

If the output was ‘hello world’, string_var would become a two element array which
echo $some_string(1) 
echo $some_string(2)

Would output 
hello
world


The long version of what I am trying to do. 

I am trying to take a .CSV spreadsheet and make each row into a separate text file with the column header followed by the data for however many columns there are. The script will also make an index file of all files generated. This is so I can use Russ Cox’s Slide+ script to view each file, make changes, notes - and eventually use another script to put all the files back together into a new .CSV.

I already have a sed script that obfuscates extra quotes and commas of each record and returns a long string that’s comma delimited


The first task of the script is to read headers (first line) and store them to be used for each file. I want to anticipate that there may be spaces in individual headings. 


Ideally, I’d like to do this in one shot, with each heading being an individual element of an array. I tried changing the comma delimiters to various types of quotes in the sed script to keep headers with spaces together, but without success. So, to move on, I obfuscated the spaces and changed the commas to spaces. This allows the header row to be broken up appropriately, but then I still have to reverse the obfuscation.

header = `{read $1 | sed ’s/^/,/; s/\\”/☹/g; s/,”([^”]*)”/,☺\1☻/g; s/,”/,☺/; :MC; s/☺([^☻]*),([^☻]*)/☺\1☯\2/g; tMC; s/^,//; s/ /♪/g; s/,/ /g’}
(I quickly typed the script line, so there may be mistakes - the characters used for obfuscation will probably be \x02 ..\x05, however, I’m using unicode characters here as they are easier to see and debug.)


I could run sed for each header every time I generate a file, but that seems quite redundant if I can just run sed for the header once and save the result in a manner that is easily accessible. 

This is my first foray into scripting, so I am not sure what is good practice and form. Any suggestions are appreciated.

Thanks and best regards.

Mack



[-- Attachment #2: Type: text/html, Size: 5975 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] rc scripts, how to get spaces in array elements generated by command output?
  2019-01-05 21:13 [9fans] rc scripts, how to get spaces in array elements generated by command output? Mack Wallace
@ 2019-01-05 23:52 ` Anthony Martin
  2019-01-06  1:05   ` Mack Wallace
  2019-01-06 14:34   ` Ethan Gardener
  0 siblings, 2 replies; 4+ messages in thread
From: Anthony Martin @ 2019-01-05 23:52 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Mack Wallace <mackbw@mapinternet.com> once said:
> My question: Is there a way to take the string output of a command that
> contains spaces and make it a single element of an array in rc script?
>
> [...]
> 
> However, if I am receiving output from sed that contains spaces from
> the following script line
> 
> string_var = `{echo some_string | sed ’s/x/y/g’}
> 
> If the output was ‘hello world’, string_var would become a two
> element array which
> echo $some_string(1) 
> echo $some_string(2)
> 
> Would output 
> hello
> world

You need to change the input field separator, $ifs.

The default value is any whitespace character:

	% x = `{echo -n hello world}
	% echo $#x
	2
	% echo $x(1)
	hello
	% echo $x(2)
	world

Using only newline as the separator yields:

	% ifs = '
		' # this is a newline character
	% 	y = `{echo -n hello world}
	% echo $#y
	1
	% echo $y(1)
	hello world

You might want to use a comma instead:

	% ifs = ,
	% z = `{echo -n hello world,good luck}
	% echo $#z
	2
	% echo $z(1)
	hello world
	% echo $z(2)
	good luck

Cheers,
  Anthony



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] rc scripts, how to get spaces in array elements generated by command output?
  2019-01-05 23:52 ` Anthony Martin
@ 2019-01-06  1:05   ` Mack Wallace
  2019-01-06 14:34   ` Ethan Gardener
  1 sibling, 0 replies; 4+ messages in thread
From: Mack Wallace @ 2019-01-06  1:05 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 2289 bytes --]

Thank you Anthony!

I had thought that IFS in Plan 9 was not the way to go after reading from ‘Rc - The Plan 9 Shell’ 

     “IFS is no longer used, except in the one case where it was indispensable:
      converting command output into argument lists during command substitution.”

The document then followed about avoiding a UNIX security hole, and lacking examples was not sure what this meant. Of course, in retrospect, it means exactly what I want to do.

So what I’ve ended up doing:

headrec = `{read $1 | sed ’s/^/,/; s/\\”/☹/g; s/,”([^”]*)”/,☺\1☻/g; s/,”/,☺/; :MC; s/☺([^☻]*),([^☻]*)/☺\1☯\2/g; tMC; s/^,//; s/,/♪/g’}
oldifs = $ifs
ifs = ♪
headers = `{echo $headrec | sed ‘/s/☹/\\”/g; s/(☺|☻)/“/g; s/☯/,/g’}
ifs = $oldifs

I’m not sure if there is a cleaner way to do this - but it gets the array of headers how they should be.

I’ll look at your other message.

Thanks,

Mack




> On Jan 5, 2019, at 6:52 PM, Anthony Martin <ality@pbrane.org> wrote:
> 
> Mack Wallace <mackbw@mapinternet.com> once said:
>> My question: Is there a way to take the string output of a command that
>> contains spaces and make it a single element of an array in rc script?
>> 
>> [...]
>> 
>> However, if I am receiving output from sed that contains spaces from
>> the following script line
>> 
>> string_var = `{echo some_string | sed ’s/x/y/g’}
>> 
>> If the output was ‘hello world’, string_var would become a two
>> element array which
>> echo $some_string(1) 
>> echo $some_string(2)
>> 
>> Would output 
>> hello
>> world
> 
> You need to change the input field separator, $ifs.
> 
> The default value is any whitespace character:
> 
> 	% x = `{echo -n hello world}
> 	% echo $#x
> 	2
> 	% echo $x(1)
> 	hello
> 	% echo $x(2)
> 	world
> 
> Using only newline as the separator yields:
> 
> 	% ifs = '
> 		' # this is a newline character
> 	% 	y = `{echo -n hello world}
> 	% echo $#y
> 	1
> 	% echo $y(1)
> 	hello world
> 
> You might want to use a comma instead:
> 
> 	% ifs = ,
> 	% z = `{echo -n hello world,good luck}
> 	% echo $#z
> 	2
> 	% echo $z(1)
> 	hello world
> 	% echo $z(2)
> 	good luck
> 
> Cheers,
>  Anthony
> 
> 


[-- Attachment #2: Type: text/html, Size: 8541 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] rc scripts, how to get spaces in array elements generated by command output?
  2019-01-05 23:52 ` Anthony Martin
  2019-01-06  1:05   ` Mack Wallace
@ 2019-01-06 14:34   ` Ethan Gardener
  1 sibling, 0 replies; 4+ messages in thread
From: Ethan Gardener @ 2019-01-06 14:34 UTC (permalink / raw)
  To: 9fans

On Sat, Jan 5, 2019, at 11:52 PM, Anthony Martin wrote:
> You need to change the input field separator, $ifs.

Yep, that was the only way to do it for a long time.
There is now a patch for a shortcut:
var=`"{cmd}

The patch is incorporated in current 9front.  Example run:

term% foo=`"{echo a b c}; echo $foo(1)
a b c



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-01-06 14:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-05 21:13 [9fans] rc scripts, how to get spaces in array elements generated by command output? Mack Wallace
2019-01-05 23:52 ` Anthony Martin
2019-01-06  1:05   ` Mack Wallace
2019-01-06 14:34   ` Ethan Gardener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).