[Thread Prev][Thread Next][Index]

Re: [ferret_users] string substitution in array



Ferret isn't really the best tool for serious string-array processing.
PyFerret is promising in this regard, since one can pass the array to
Python, manipulate it, and then pass it back to Ferret.

But in vanilla Ferret, it's often easiest to just dump the strings to
a file, process that file with shell tools (sed, tr, cut, awk, python,
perl, etc.), then read it back in:

yes? let a = {"a_old", "bb_old", "ccccc_old"}
yes? list/noh/nor/clob/file="a.txt" a
yes? sp cut -d \" -f2 a.txt | sed "s/old/new/g" > b.txt
yes? sp rm a.txt
yes? let b = spawn("cat b.txt")
yes? list a,b
             X: 0.5 to 3.5
 Column  1: A is {"a_old", "bb_old", "ccccc_old"}
 Column  2: B is SPAWN("cat b.txt")
                  A       B
1   / 1: "a_old"     "a_new"
2   / 2: "bb_old"    "bb_new"
3   / 3: "ccccc_old" "ccccc_new"
yes? sp rm b.txt

This works, though we have to keep the file b.txt around until we're
done evaluating the variable b.

Also note that the XSEQUENCE() in your example was redundant, since
the {} array constructor is already x-oriented by default.

Andrew


On Tue, Sep 22, 2015 at 4:10 PM, Marco van Hulten <mvhulten@xxxxxxxxxxxx> wrote:
> Dear Ferrets,
>
> I would like to substitute substrings in an array of strings.  For a
> single string this is easy to do.  Say I want to replace "old" for "new"
> in the following example:
>
> let test = "abc_old_xyz"
> let myInd = StrIndex( test, "old" )
> list SubString( test, 1, `myInd-1` ) + "new" + SubString( test, `myInd+3`, StrLen(test) )
>
> I want to do the same for an arbitrary array (for readability I leave
> out the option of arbitrary strings or substrings):
>
> let strArray = XSequence( {"a_old", "bb_old", "ccccc_old"} )
> let newArray = SubString(strArray, 1, 2) + "new"
>
> This works, but suppose I have an array with the locations of the
> character just before 'old' that I want to replace, then this comes
> closer:
>
> let myInd = XSequence( {2, 3, 6} )
> let newArray = SubString(strArray, 1, myInd) + "new"
>
> Of course, I'd like to search for the string that I want to replace, so
> I try:
>
> let myInd = StrIndex( strArray, "old" )
> let newArray = SubString(strArray, 1, myInd) + "new"
>
> We need to shift the substring to the left, so:
>
> let newArray = SubString(strArray, 1, myInd-1) + "new"
>
> This works.  It is left as an exercise to the reader what to do when
> there are characters following the replacement.
>
> One may think that this is easier if you spawn the sed(1) command, as
> that does not require index manipulation:
>
> let test = "abc_old_xyz"
> list SPAWN( "echo `test` | sed '{s/old/new/}'" )
>
> With an array of strings it becomes like this:
>
> let strArray = XSequence( {"a_old", "bb_old", "ccccc_old"} )
> let newArray = SPAWN( "echo `strArray` | sed '{s/old/new/}'" )
>
> That doesn't work, since strArray is an array while grave accents want
> to evaluate it to a scalar.  I tried it in a loop, and by use of
> symbols (which are evaluated even earlier than grave accents), but I
> cannot figure it out.  So, in this case, while string manipulation may
> be a bit circuitous in Ferret, it is a method that works.  But please
> let me know if you have a better solution.
>
> Marco
>
> --
> Laboratoire des Sciences du Climat et l'Environnement (LSCE)
> Tel: +33 1 6908 3876
> http://www.lsce.ipsl.fr/Pisp/marco.van-hulten/


[Thread Prev][Thread Next][Index]
Contact Us
Dept of Commerce / NOAA / OAR / PMEL / Ferret

Privacy Policy | Disclaimer | Accessibility Statement