Reputation: 1647
I have the following data in array:
MY_ARR[0]="./path/path2/name.exe 'word1 word2' 'name1,name2'"
MY_ARR[1]="./path/path2/name.exe 'word1 word2' 'name3,name4,name5'"
MY_ARR[2]=".name.exe 'word1 word2'"
MY_ARR[3]="name.exe"
MY_ARR[4]="./path/path2/name.exe 'word1 word2' 'name1'"
MY_ARR[5]="./path/path2/name.exe 'word1 word2' 'name.exe, name4.exe, name5.exe'"
I want to divide it into two variables: $file
and $parameter
.
Example:
file="./path/path2/name.exe"
parameter="'word1 word2' 'name1,name2'"
I can do it with awk:
parameter=$(echo "${MY_ARR[1]}" | awk -F\' '{print $2 $4}')
file=$(echo "${MY_ARR[1]}" | awk -F\' '{print $1}')
This needs to remove trailing spaces and looks to complicated.
Is there a better way to do it?
Upvotes: 8
Views: 21892
Reputation: 11633
Unless I'm missing something, simplest and most portable way would be to just use two variations of bash expansion for this.
file="${MY_ARR[0]%%' '*}"
parameter="${MY_ARR[0]#*' '}"
Explanation
"${MY_ARR[0]%%' '*}"
- This removes the first space and anything after it, and returns remaining part"${MY_ARR[0]#*' '}"
- This removes everything up to the first space, and returns the remaining partFor a more detailed explanation, see the Parameter Expansion
section of the bash man page
Upvotes: 1
Reputation: 290515
It looks like the separator between the fields is an space. Hence, you can use cut
to split them:
file=$(echo "${MY_ARR[1]}" | cut -d' ' -f1)
parameter=$(echo "${MY_ARR[1]}" | cut -d' ' -f2-)
-f1
means the first parameter.-f2-
means everything from the second parameter.Upvotes: 15
Reputation: 21
Given this array:
MY_ARR[0]="./path/path2/name.exe 'word1 word2' 'name1,name2'"
MY_ARR[1]="./path/path2/name.exe 'word1 word2' 'name3,name4,name5'"
MY_ARR[2]=".name.exe 'word1 word2'"
MY_ARR[3]="name.exe"
MY_ARR[4]="./path/path2/name.exe 'word1 word2' 'name1'"
MY_ARR[5]="./path/path2/name.exe 'word1 word2' 'name.exe, name4.exe, name5.exe'"
Lets make 2 new arrays MY_FILES and MY_PARAMETERS
for MY_ARR_INDEX in ${!MY_ARR[*]} ; do
######
# Set the current file in new array.
MY_FILES[ ${MY_ARR_INDEX} ]=${MY_ARR[ ${MY_ARR_INDEX} ]// *}
######
# Set the current parameters in new array
MY_PARAMETERS[ ${MY_ARR_INDEX} ]=${MY_ARR[ ${MY_ARR_INDEX} ]#* }
######
# Show the user whats happening
# (from here until done is just printing info.)
printf "MY_FILES[ ${MY_ARR_INDEX} ]=\"%s\" ; MY_PARAMETERS[ ${MY_ARR_INDEX} ]=\"%s\"\n" \
\
"${MY_ARR[ ${MY_ARR_INDEX} ]// *}" "${MY_ARR[ ${MY_ARR_INDEX} ]#* }"
done
MY_FILES[ 0 ]="./path/path2/name.exe" ; MY_PARAMETERS[ 0 ]="'word1 word2' 'name1,name2'"
MY_FILES[ 1 ]="./path/path2/name.exe" ; MY_PARAMETERS[ 1 ]="'word1 word2' 'name3,name4,name5'"
MY_FILES[ 2 ]=".name.exe" ; MY_PARAMETERS[ 2 ]=" 'word1 word2'"
MY_FILES[ 3 ]="name.exe" ; MY_PARAMETERS[ 3 ]="name.exe"
MY_FILES[ 4 ]="./path/path2/name.exe" ; MY_PARAMETERS[ 4 ]="'word1 word2' 'name1'"
MY_FILES[ 5 ]="./path/path2/name.exe" ; MY_PARAMETERS[ 5 ]="'word1 word2' 'name.exe, name4.exe, name5.exe'"
How to access each file:
for MY_ARR_INDEX in ${!MY_FILES[*]} ; do
CUR_FILE=${MY_FILES[ ${MY_ARR_INDEX} ] }
echo "# Do something with this file: ${CUR_FILE}"
done
Output:
Do something with this file: ./path/path2/name.exe
Do something with this file: ./path/path2/name.exe
Do something with this file: .name.exe
Do something with this file: name.exe
Do something with this file: ./path/path2/name.exe
Do something with this file: ./path/path2/name.exe
How to access each parameter :
for MY_ARR_INDEX in ${!MY_PARAMETERS[*]} ; do
CUR_FILE=${MY_FILES[ ${MY_ARR_INDEX} ]}
echo "# Do something with this parameter: ${CUR_FILE}"
done
Output:
Do something with this parameter: ./path/path2/name.exe
Do something with this parameter: ./path/path2/name.exe
Do something with this parameter: .name.exe
Do something with this parameter: name.exe
Do something with this parameter: ./path/path2/name.exe
Do something with this parameter: ./path/path2/name.exe
Since ${!MY_FILES[ [*]} results in the index NUMBERS of array MY_FILES you can also use the same index numbers to access the other arrays.In this way, you may access multiple columns of data in the same loop. Like so:
################
#
# Print each file and matching parameter(s)
#
################
# Set a printf format string so we can print all things nicely.
MY_PRINTF_FORMAT="# %25s %s\n"
################
#
# Print the column headings and use index numbers
#
# to print adjacent array elements.
#
################
(
printf "${MY_PRINTF_FORMAT}" "FILE" "PARAMETERS" "----" "----------"
for MY_ARR_INDEX in ${!MY_FILES[*]} ; do
printf "${MY_PRINTF_FORMAT}" "${MY_FILES[ ${MY_ARR_INDEX} ]}" "${MY_PARAMETERS[ ${MY_ARR_INDEX} ]}"
done
)
Output :
FILE PARAMETERS
---- ----------
./path/path2/name.exe 'word1 word2' 'name1,name2'
./path/path2/name.exe 'word1 word2' 'name3,name4,name5'
.name.exe 'word1 word2'
name.exe name.exe
./path/path2/name.exe 'word1 word2' 'name1'
./path/path2/name.exe 'word1 word2' 'name.exe, name4.exe, name5.exe'
Upvotes: 2
Reputation: 47239
You can use read
:
$ read file parameter <<< ${MY_ARR[1]}
$ echo "$file"
./path/path2/name.exe
$ echo "$parameter"
'word1 word2' 'name3,name4,name5'
Upvotes: 5