Reputation: 8452
I'm trying to transform a given line to an array, for example this line :
My first\t \tHello world
to the following ksh/bash array:
[0]="My first"
[1]=""
[2]="Hello world"
My code:
TAB=`printf '\011'`
query()
{
echo "$1"|awk -F"$TAB" '
{
for(i = 0; i < NF; i++)
QueryArray[i]=$i
}';
}
line=`head -n 1 myFile`
typeset -a QueryArray;
query "$line"
echo "Array length: ${#QueryArray[*]}"
echo "- " ${QueryArray[0]}
echo "- " ${QueryArray[1]}
echo "- " ${QueryArray[2]}
but doesn't work, any suggestions?
Thanks.
Upvotes: 1
Views: 1631
Reputation: 247012
I have an older ksh that does not understand $'ANSI'
strings, so:
str2array () {
typeset arrayname=$1
typeset IFS=$2
shift 2
eval "set -A $arrayname \$*"
}
s="Hello World" # tabs entered literally with "Ctrl-V tab"
str2array myarray " " "$s" # another literal tab as 2nd parm
typeset -i i=0
while [[ $i -lt ${#myarray[@]} ]]; do
printf "%d\t%s\n" $i "${myarray[$i]}"
i=$(( i+1 ))
done
for bash:
str2array () {
local arrayname=$1
local IFS=$2
shift 2
eval "$arrayname=( \$* )"
}
s=$'hello\t\tworld'
str2array myarray $'\t' "$s"
for (( i=0; i < ${#myarray[@]}; i++ )); do
printf "%d\t%s\n" $i "${myarray[$i]}"
done
I'm getting the same result ar Arnaud's comment to David: with "word\t\tword", the middle field is being dropped. I don't see that with a different delimiter such as colon.
ksh
Blank Interpretation
After parameter and command substitution, the results of substitutions are scanned for the field separator characters (those found in IFS) and split into distinct arguments where such characters are found. Explicit null arguments ( "" ) or ('') are retained. Implicit null arguments (those resulting from parameters that have no values) are removed.
bash
Word Splitting
... The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters. If IFS is unset, or its value is exactly<space><tab><newline>
, the default, then sequences of<space>
,<tab>
, and<newline>
at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters space and tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter. If the value of IFS is null, no word splitting occurs.
Upvotes: 1
Reputation: 107080
Doesn't work in KSH.
You need to use typeset
instead of declare
, and use the function
keyword. Otherwise, satyajit's answer works just fine.
Kornshellified for you...
function query
{
IFS=$'\t'
ind=0
for i in $1
do
QueryArray[$ind]=$i
let "ind+=1"
done
unset IFS
}
typeset -a QueryArray #Actually this is optional in Kornshell
query "Hello World" #Hello\t \tWorld
# What the heck? Might as well go all Korn: print vs. echo
print "Array length: ${#QueryArray[*]}"
print -- "- ${QueryArray[0]}"
print -- "- ${QueryArray[1]}"
print -- "- ${QueryArray[2]}"
Upvotes: 1
Reputation: 3859
query()
{
IFS=$'\t'
ind=0
for i in $1
do
QueryArray[$ind]=$i
let "ind+=1"
done
unset IFS
}
declare -A QueryArray;
query "Hello World" #Hello\t \tWorld
echo "Array length: ${#QueryArray[*]}"
echo "- " ${QueryArray[0]}
echo "- " ${QueryArray[1]}
echo "- " ${QueryArray[2]}
Upvotes: 1