bug-bash@gnu.org

2021-08-23 Thread Chet Ramey
On 8/22/21 5:11 PM, Emanuele Torre wrote:
> It would be nice to have a parameter transformation (e.g. "${par@p}")
> that expands $par to a string that will not be expanded by PS1, PS2, &c.

So you want it to be expanded at some point, but its value not subject to
any of the prompt string expansions (\a, \d, \t, and so on)?


> 
> example:
> 
>   tmp_var=$(blabla) # this variable will not exist when PS1 is expanded

This seemns to be the key requirement. Otherwise, you would be able to
simply write PS1="blabla \${tmp_var} blabla" as others have suggested.

I'm not sure that requires a new transformation (which would have to be
much more completely specified than it has been so far).


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



efficient way to use matched string in variable substitution

2021-08-23 Thread L A Walsh

Starting with a number N, is there
an easy way to print its digits into an array?
I came up with a few ways, but thought this
would be nice (with '\1' or '$1' being what was matched
in the 1st part), this could be statement:

arr=(${N//[0-9]/\1 })
 or
arr=(${N//[0-9]/$1 })

Instead of using loops (my=declare):


 n=988421
 for x in 0 1 2 3 4 5 6 7 8 9;do n=${n//$x/$x }; done
 arr=($n)
 my -p arr

declare -a arr=([0]="9" [1]="8" [2]="8" [3]="4" [4]="2" [5]="1")

or w/substrings:


 for ((d=0; d<${#n};d+=1)); do arr+=(${n:$d:1}); done
 my -p arr

declare -a arr=([0]="9" [1]="8" [2]="8" [3]="4" [4]="2" [5]="1")

Not a big thing, but having some way for the match of an RE
to be specified in the output would be handy...





Re: efficient way to use matched string in variable substitution

2021-08-23 Thread Greg Wooledge
On Mon, Aug 23, 2021 at 11:36:52AM -0700, L A Walsh wrote:
> Starting with a number N, is there
> an easy way to print its digits into an array?

"Easy"?  Or "efficient"?  Your subject header says one, but your body
says the other.

> arr=(${N//[0-9]/\1 })

> arr=(${N//[0-9]/$1 })

Obviously those don't work.


> >  for x in 0 1 2 3 4 5 6 7 8 9;do n=${n//$x/$x }; done
> >  arr=($n)

That doesn't look particularly elegant to me.  But we can throw it on the
pile.

unicorn:~$ f1() { local x n="$1" arr; for x in 0 1 2 3 4 5 6 7 8 9; do 
n=${n//$x/$x }; done; arr=($n); }
unicorn:~$ time for ((i=1; i<=1; i++)); do f1 682390; done
real 0.444  user 0.444  sys 0.000


> >  for ((d=0; d<${#n};d+=1)); do arr+=(${n:$d:1}); done

That's the approach I'd start with, with a few minor changes.

unicorn:~$ f2() { local i n="${#1}" arr; for ((i=0; i 0)); do 
tmp+=("$((n%10))"); ((n /= 10)); done; for ((i=${#tmp[@]}-1; i >= 0; i--)); do 
arr+=("${tmp[i]}"); done; }
unicorn:~$ time for ((i=1; i<=1; i++)); do f3 682390; done
real 0.695  user 0.691  sys 0.000

This one is less efficient, no doubt because of the extra time needed
to reverse the temporary array.


If we take steps to avoid that reversal, let's see what happens:

unicorn:~$ f4() { local n="$1" i=${#1} arr; while ((n > 0)); do 
arr[--i]=$((n%10)); ((n /= 10)); done; }
unicorn:~$ time for ((i=1; i<=1; i++)); do f4 682390; done
real 0.356  user 0.356  sys 0.000

Looks like we have a winner.



Re: efficient way to use matched string in variable substitution

2021-08-23 Thread Oğuz
23 Ağustos 2021 Pazartesi tarihinde L A Walsh  yazdı:

> Starting with a number N, is there
> an easy way to print its digits into an array?
> I came up with a few ways, but thought this
> would be nice (with '\1' or '$1' being what was matched
> in the 1st part), this could be statement:


If memory serves, the ampersand character will have this function in bash
5.2.


>
> arr=(${N//[0-9]/\1 })
>  or
> arr=(${N//[0-9]/$1 })
>
> Instead of using loops (my=declare):
>
>  n=988421
>>  for x in 0 1 2 3 4 5 6 7 8 9;do n=${n//$x/$x }; done
>>  arr=($n)
>>  my -p arr
>>
> declare -a arr=([0]="9" [1]="8" [2]="8" [3]="4" [4]="2" [5]="1")
>
> or w/substrings:
>
>  for ((d=0; d<${#n};d+=1)); do arr+=(${n:$d:1}); done
>>  my -p arr
>>
> declare -a arr=([0]="9" [1]="8" [2]="8" [3]="4" [4]="2" [5]="1")
>
> Not a big thing, but having some way for the match of an RE
> to be specified in the output would be handy...
>
>
>
>

-- 
Oğuz


Re: efficient way to use matched string in variable substitution

2021-08-23 Thread Chet Ramey
On 8/23/21 3:13 PM, Oğuz wrote:
> 23 Ağustos 2021 Pazartesi tarihinde L A Walsh  yazdı:
> 
>> Starting with a number N, is there
>> an easy way to print its digits into an array?
>> I came up with a few ways, but thought this
>> would be nice (with '\1' or '$1' being what was matched
>> in the 1st part), this could be statement:
> 
> 
> If memory serves, the ampersand character will have this function in bash
> 5.2.

Yes, it's tagged for bash-5.2.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: efficient way to use matched string in variable substitution

2021-08-23 Thread L A Walsh




On 2021/08/23 12:10, Greg Wooledge wrote:

On Mon, Aug 23, 2021 at 11:36:52AM -0700, L A Walsh wrote:
  

Starting with a number N, is there
an easy way to print its digits into an array?



"Easy"?  Or "efficient"?  Your subject header says one, but your body
says the other.
  

Efficient, in my vocabulary, also includes my time in coding, typing
and remembering ... i.e. it's not just limited to computer time. :-)

However, thanks for the examples!  I do appreciate them!

The problem with using timing tests on interpreted code, is that
often what takes 'X' time today, may take more or less tomorrow
after many refactorings, patches and code-restructuring.

That isn't to day I don't use the same methods at times on specific
problems...oh well...

Computer algorithms, coding styles, languages and benchmarks are pretty
fleeting these days...not to mention different on different platforms and
by different compilers...sigh.

I remember counting clock cycles in assembler code...oi!



Re: efficient way to use matched string in variable substitution

2021-08-23 Thread Greg Wooledge
On Mon, Aug 23, 2021 at 12:41:58PM -0700, L A Walsh wrote:
> 
> 
> On 2021/08/23 12:10, Greg Wooledge wrote:
> > On Mon, Aug 23, 2021 at 11:36:52AM -0700, L A Walsh wrote:
> > > Starting with a number N, is there
> > > an easy way to print its digits into an array?
> > 
> > "Easy"?  Or "efficient"?  Your subject header says one, but your body
> > says the other.
> Efficient, in my vocabulary, also includes my time in coding, typing
> and remembering ... i.e. it's not just limited to computer time. :-)
> 
> However, thanks for the examples!  I do appreciate them!

Well, the most important thing here is that your first working example
only works on input strings which contain no whitespace or globbing
characters, because you're using word splitting.  As long as your input
is a "number", this works.  But if you want to use this same function
on an arbitrary input string, it will not.

The proposed variant using ${input//?/& } (in a future version of bash)
will have the same issue.

I wrote another example after sending the last email.  Well, two actually,
but they're almost identical:


unicorn:~$ f5() { local i n=${#1} arr; while ((i < n)); do arr[i]="${1:i:1}"; 
((i++)); done; }
unicorn:~$ time for ((i=1; i<=1; i++)); do f5 682390; done
real 0.420  user 0.410  sys 0.000


unicorn:~$ f6() { local i n=${#1} arr; for ((i=0; i