1

I need to create a dynamic variable name for some arrays and fill it with multi-line text.

What I actually have is this :

#!/bin/bash

IFS=$'\n'
# Set an array with 1 item
ARRAY=("Item1")
# Get a description for the last item from a simple text file
DESCRIPTION=("$(cat test1.txt)")
# Get the number of items in the array
ARRAY_ITEMS_COUNT=${#ARRAY[@]}
# Create a variable name containing the number of items in the array as identifier
# and fill it with the description
eval ARRAY_ITEM${ARRAY_ITEMS_COUNT}_DESCRIPTION="(\"${DESCRIPTION[@]}\")"

# Display some results
echo "ARRAY_ITEM1_DESCRIPTION[@] = \"${ARRAY_ITEM1_DESCRIPTION[@]}\""
echo "ARRAY_ITEM1_DESCRIPTION[0] = \"${ARRAY_ITEM1_DESCRIPTION[0]}\""
echo "ARRAY_ITEM1_DESCRIPTION[1] = \"${ARRAY_ITEM1_DESCRIPTION[1]}\""

echo

# Same as above with a different text file
ARRAY=("Item1" "Item2")
DESCRIPTION=("$(cat test2.txt)")
ARRAY_ITEMS_COUNT=${#ARRAY[@]}

# Get an error here due to the ' character used in the text file
eval ARRAY_ITEM${ARRAY_ITEMS_COUNT}_DESCRIPTION="(\"${DESCRIPTION[@]}\")"

echo "ARRAY_ITEM2_DESCRIPTION[@] = \"${ARRAY_ITEM2_DESCRIPTION[@]}\""
echo "ARRAY_ITEM2_DESCRIPTION[0] = \"${ARRAY_ITEM2_DESCRIPTION[0]}\""
echo "ARRAY_ITEM2_DESCRIPTION[1] = \"${ARRAY_ITEM2_DESCRIPTION[1]}\""

The files "test1.txt" and "test2.txt" are as follow :

test1.txt

Simple text file with multi-lines used as
a test without special characters inside.

test2.txt

Simple text file with multi-lines used as
a test with single ' and double " quotes.

Expected result :

ARRAY_ITEM1_DESCRIPTION[@] = "Simple text file with multi-lines used as
a test without special characters inside."
ARRAY_ITEM1_DESCRIPTION[0] = "Simple text file with multi-lines used as"
ARRAY_ITEM1_DESCRIPTION[1] = "a test without special characters inside."

ARRAY_ITEM2_DESCRIPTION[@] = "Simple text file with multi-lines used as
a test with single ' and double " quotes."
ARRAY_ITEM2_DESCRIPTION[0] = "Simple text file with multi-lines used as"
ARRAY_ITEM2_DESCRIPTION[1] = "a test with single ' and double " quotes."

Current result :

ARRAY_ITEM1_DESCRIPTION[@] = "Simple text file with multi-lines used as
a test without special characters inside."
ARRAY_ITEM1_DESCRIPTION[0] = "Simple text file with multi-lines used as
a test without special characters inside."
ARRAY_ITEM1_DESCRIPTION[1] = ""

./test.sh: eval: line 28: unexpected EOF while looking for matching `"'
./test.sh: eval: line 29: syntax error: unexpected end of file
ARRAY_ITEM2_DESCRIPTION[@] = ""
ARRAY_ITEM2_DESCRIPTION[0] = ""
ARRAY_ITEM2_DESCRIPTION[1] = ""

I tried a lot of things but it never gives me what is expected, so can someone help me solve the 2 issues I have there please :

  • How to get proper array containing each line of the text file on each index
  • How to make it work even with quotes characters in the texts

EDIT : Working solution (bash version > 4) is :

#!/bin/bash

# Set an array with 1 item
ARRAY=("Item1")
# Get the number of items in the array
ARRAY_ITEMS_COUNT=${#ARRAY[@]}
# Create a variable name containing the number of items in the array as identifier
# and fill it with the description
readarray -t "ARRAY_ITEM${ARRAY_ITEMS_COUNT}_DESCRIPTION" < test1.txt

# Display some results
echo "ARRAY_ITEM1_DESCRIPTION[@] = \"${ARRAY_ITEM1_DESCRIPTION[@]}\""
echo "ARRAY_ITEM1_DESCRIPTION[0] = \"${ARRAY_ITEM1_DESCRIPTION[0]}\""
echo "ARRAY_ITEM1_DESCRIPTION[1] = \"${ARRAY_ITEM1_DESCRIPTION[1]}\""

echo

# Same as above with a different text file
ARRAY=("Item1" "Item2")
ARRAY_ITEMS_COUNT=${#ARRAY[@]}

# Get an error here due to the ' character used in the text file
readarray -t ARRAY_ITEM${ARRAY_ITEMS_COUNT}_DESCRIPTION < test2.txt

echo "ARRAY_ITEM2_DESCRIPTION[@] = \"${ARRAY_ITEM2_DESCRIPTION[@]}\""
echo "ARRAY_ITEM2_DESCRIPTION[0] = \"${ARRAY_ITEM2_DESCRIPTION[0]}\""
echo "ARRAY_ITEM2_DESCRIPTION[1] = \"${ARRAY_ITEM2_DESCRIPTION[1]}\""

Thanks for your help, have a nice day.

Slander

2
  • Slander, I'm sure there is a way to do this purely in bash, but whenever I'm working with single and double quotes (or possibly other nefarious characters: $, %, *, !). I'd start looking at a scripting language better suited to that environment (e.g. perl or python). Commented Mar 17, 2014 at 13:36
  • As mentioned below, there is an easy way to do it without mixing languages. Bash is powerfull... Thanks anyway ;) Commented Mar 17, 2014 at 14:30

1 Answer 1

2

When you call cat in an array assignment you shouldn't quote it if you want the file to be read line by line. Because if you do so the contents of the file will be handled as one string/one line. So it won't get read line by line. Just try:

DESCRIPTION=($(cat test1.txt))

Also if you are using Bash version 4 you could use bash builtin command readarray to generate an array:

readarray -t DESCRIPTION < "test1.txt"

For Bash version < 4 this could be an alternative to cat and readarray:

IFS=$'\n' read -d -r -a DESCRIPTION < "test1.txt"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.