In the world of programming, every language is equipped with a crucial tool named array. Data structure in origin; arrays can change the way you store and manipulate data within shell scripting in Bash. It is a cardinal skill to have whether you are an experienced or novice script developer. Therefore, in this article, I will dive deep into Bash array and display the ins and outs to supercharge your scripting mastery.
What is an Array in Bash?
In Bash, an array is a collection of values. It’s a list containing multiple values under a single variable entity. The array values are typically called elements managed and referenced in an indexed approach. Unlike programming languages such as C or C++, bash arrays function as the one-dimensional storage of diversified data types. For example, an array in bash can seamlessly organize number and string data simultaneously in a structured manner. Another attribute that strengthens these arrays is their dynamic nature of size and memory allocation.
Now that you have a basic idea about bash arrays, I will walk you through the in-depth discussion in the following sections.
Applications of Bash Array
You can use bash arrays in a wide variety of applications. Some of the most common use cases are:
- Data Storage: The Bash arrays act as an efficient medium to store information when used inside shell scripts. On top of that, you can manipulate data as per the requirements.
- Configuration Management: The user can utilize bash arrays for managing system configuration within bash scripts.
- File Handling: You can access files using bash arrays that are particularly useful for file content processing and analysis.
- Processes and Service Management: Bash arrays can handle necessary entities of system administration scripts such as service names, process IDs, and other related information.
- Data Validation and Verification: Bash arrays can work as the storage of reference data as far as the verification procedure is concerned. For instance, to check the validity of a user’s entered value by comparing it to the actual values in the array.
Types of Bash Array
In Bash, there are mainly two types of arrays:
- Numerically Indexed Array: The array form that references the data elements using indices starting from ‘0’. So, if an array contains two elements, the first value is placed at index 0 while the second element (last element) is at index 1.
- Associative Array: The associative array keeps the data values using named indices. In other words, this array uses strings as indices to reference values.
According to the dimension, bash arrays can be categorized into the following kinds:
- One-dimensional Array (1-D Array): This is the most frequent one. It is a list of values that is also known as a numerically indexed array. So, these are zero-indexed and the elements are accessed through the indices.
- Multidimensional Array: Bash does not exactly have the native support for true multidimensional arrays like languages such as Python or C++. However, it can be simulated using the concept of creating an array of arrays where the elements are represented in a grid or matrix-like structure.
The upcoming parts will provide more information on bash arrays. Just follow my lead.
Bash Array Basics
From this section, I will continue to talk about bash arrays displaying the pragmatic aspects. Specifically, root-level array operations like array declaration, printing elements, etc. will be the scope of this feature. So without further ado, let’s dive in.
1. Declaring an Array in Bash
The declaration can be termed the foremost step when you intend to work with arrays in Bash though it is not mandatory since Bash is a dynamically typed scripting language. You can declare a bash array by using the following syntax with the built-in declare command:
declare -a <array_name>
- declare: Bash command used to set the array variable attribute.
- -a: Option indicating the declaration of an indexed array.
- <array_name>: The name you want to assign to the array.
Now, for example, I will create an array named tennis_kit by utilizing the following bash script code. Go through the below Bash script to practically explore the process:
#!/bin/bash
#Declaring an indexed array using the declare command
declare -a tennis_kit
#print a message if no error occurs in the declaration
echo “index array declared”
In, #!/bin/bash
, #!
Is called shebang. It indicates the system uses the bash interpreter for executing the script. The 3rd line declares an array named tennis_kit using the explicit declare command and -a
indicates that I have created a numerically indexed array. Finally, the last line prints a message if the declaration is successful and error-free.
2. Printing Arrays in Bash
Printing Bash arrays is a very common practice in shell scripting. This is also handy as far as the output verification is concerned and, in bash, there are several ways. So, you can print all the contents of an array using the following lines in your bash scripting code:
echo ${array[@]}
Likewise, the below code also returns the same output:
echo ${array[*]}
- echo: Bash command used to set the array variable attribute.
- ${}: Used to retrieve the value of a variable.
- arr_name: The name of the array you want to assign.
- [@]/[*]: Points out the referencing of all elements of the array.
Okay, now, follow the below Bash script to see the pragmatic aspects of the aforesaid concept:
#!/bin/bash
#Array declaration with elements
heroes=(Batman Ironman Spiderman)
#print contents only with @ operator
echo "using @: ${heroes[@]}"
#print arrays elements with string and * operator
echo "using *: ${heroes[*]}"
In the above snippet, You see I have created an array named heroes with 3 elements and printed the contents using the echo ${heroes[ ]}
expression. Here, [@] and [*] both yield the same result and can be used interchangeably. In addition, you can discern that the array contents are displayed in a single line.
Basic Operations on Arrays in Shell Scripts
The target of this feature is to get you acquainted with the primary operating tools regarding Bash arrays that you will utilize frequently in script development. Specifically, I will discuss the accessing, printing, and looping through array elements. Additionally, I illustrate the way to delete an array completely from your system.
1. Traversing an Array in Bash
Accessing the elements is an important task for working with arrays in any programming language. It is helpful for not only printing the elements but also manipulating the array in various ways. Likewise, in bash, you can use methods involving some super simple scripting to achieve this. Nevertheless, in the coming section, I will guide you through the way of accessing bash array elements by exploiting their indices.
Previously while discussing the indexed array, I mentioned that the indices begin from 0 and increase by 1. So, for example, to get the second value of the array, you have to code the below line in the bash script:
echo ${array_name[index_num]}
- echo: Command that prints the array elements to the terminal.
- ${}: Used to retrieve the value of a variable.
- array_name: The name you want to assign to the array.
- [index_num]: Number used to locate the position of the intended array item.
Now, to play around with the index numbers for element retrieval, you can execute the following script:
#!/bin/bash
#Declaring and initializing an indexed array
fruits=(apple, banana, grape)
#Access the first element
echo "first value: ${fruits[0]}"
#Access the second and last array elements
echo "second value: ${fruits[1]}"
echo "last value: ${fruits[2]}"
In the third line, I have created an array named fruits and initialized it with three elements (fruit names). Then, I used the index 0 to get the value of the first index. Also, I accessed the second and last items using indices 1, and 2 that you see in the afterward lines. In all cases, the standard echo command prints the items of the fruits array to the command prompt.
Now, in this script, I have printed the contents of the fruits array using their indices.
2. Print Specific Elements of an Array in Bash
Apart from printing the entire array, you can also print any specific elements of that array. And, this is also done using indices. Take a look at the below script for clarity:
#!/bin/bash
#Declaring and initializing an array
currency=(dollar taka rupee yen pound franc dinar dirham)
#print the second fifth and last elements
echo "total elements: ${#currency[@]} but printed only below ones:"
echo "${currency[1]}"
echo "${currency[4]}"
echo "${currency[7]}"
In this Bash script, I declared an array named currency and initialized it with 8 values. Then, I displayed only the elements of indices 1, 4, and 7 using the echo command.
3. Calculating the Length of an Array in Bash
It must be noted that the array in Bash is a dynamic one without having any predefined size like Python arrays and the array length increases with the insertion of elements. Thus, for dynamic array handling and efficacious memory management, knowing the current array length is a pertinent step that is also the scope of this feature.
The process of retrieving the bash array length is very straightforward. Just add the following line in the bash script code after the creation of the array:
echo ${#arr_name[@]}
- ${}: Used to retrieve the value of a variable.
- arr_name: The name of the array you want to assign.
- [@]: Points out the referencing of all elements of the array.
Note: To make the code more readable, you can assign the value of the length (the result of the expression ${#arr_name[@]} ) to a new variable and print it to get the length.
length= ${#arr_name[@]}
echo $length
In the following script, I will create an array and print its length as a quick demonstration:
#!/bin/bash
#Array creation
cards=(hearts diamonds spades clubs)
#Array length calculation and assigning to a new variable named len
len=${#cards[@]}
#printing array length to the prompt
echo $len
In this script, I have first created the cards array with 4 elements. Then, I added the expression ${#cards[@]}
which gets the array length and I stored the value in a variable named len afterward. On an end note, I printed the length to the terminal executing the echo command followed by the len variable prefixed with $ sign.
Note: The expression ${#cards[*]} also returns the length of the array.
4. Looping Through an Array in Bash
Accessing and printing the bash array elements using the indices is the most frequent method as far as array handling is concerned. Similarly, you can use for loops to access the bash array elements using the following syntax:
for items in ${arr_name[@]}
do
echo $items
done
- for: Keyword to use for loop for iterating the array items.
- items: Example of a user-defined variable holding the current array element.
- in: Indicates the set of array values to iterate over.
- ${arr_name}: The array expansion to get the element values.
- [@]: Indicates that you want to iterate over an array’s elements.
Now, follow the below script to learn how to iterate over a Bash array:
#!/bin/bash
#Declaring an indexed array and assigning it with values
fruits=(apple banana grape)
#looping through the elements to print
for elems in ${fruits[@]}
do
echo $elems
done
Here, I declared and assigned the array using for loops maintaining the standard syntax where elems takes each fruit name (apple, banana, grape). Then the echo command prints the fruit name to the terminal screen in a new line until a full iteration since I used [@] notifying that I want to loop through the entire array.
5. Deleting a Bash Array
If you want to delete an array after doing all the necessary operations from your system, all you need to do is use the unset command but with a different gist. This time DO NOT specify any index number like you did in terms of removing array elements.
Here, in this script, I will show you the deletion process of a bash array:
#!/bin/bash
# the array to be deleted
language=(c python Golang java)
#deleting the entire array
unset language
#printing array elements
echo ${language[@]}
#printing array indices
echo ${!language[@]}
So, in the above bash script, I have taken an array with 4 elements. Then, the use of the unset command deletes the entire array. As a result, when I try to print the array elements and their indices, there is no output shown on the terminal screen even after executing the delete.sh script.
The aforementioned bash program prints messages instead of printing the array elements and indices which means that I have deleted the array called language using the unset command.
Array Manipulation in Bash
Till now, I have introduced you to the basics of Bash arrays to get you started. Now, in this section, my prime agenda is to shed light on array manipulation through the illustration of various operations such as appending elements, inserting elements into the array, updating the array, merging two arrays, etc. using Bash scripts.
A. Append Elements to an Array in Bash
In Bash or any programming language, appending refers to the addition of elements in an array. In the following sub-section, I will show you the addition of array elements with hands-on scripting examples for indexed arrays. And the addition of an indexed array element is very easy. You only have to use the below line of code in the bash script:
array_name+=(element to be appended)
- array_name: The array name you want to assign.
- +=: Operator that adds an element to the end of the array.
- element to be appended: The new element you intend to append to the old array.
Let’s see a Bash script example for a complete overview of the concept:
#!/bin/bash
#The main array
distros=(ubuntu kali arch)
#prints array with 3 existing elements
echo "array before appending: ${distros[@]}"
#new value to append
distros+=(redHat)
#Prints array with newly added element redHat
echo "array after appending: ${distros[@]}"
In the aforementioned script, I started with an array named distros which had 3 elements. Then, using the expression distros+=(redHat), I have appended the new element redHat to the array. As a result, the distros array now has 4 elements which is verified by printing the array using the standard echo command.
This script uses the += operator and appends a new element redHat to the existing distros array.
B. Insert Elements to an Array in Bash
Apart from appending array elements at the end of the array, you can insert elements at a specific position of the array. It is adding but with an index assignment. The general syntax to insert an element into an array is as follows:
array_name[position]= element to be inserted
Now, I will show a bash script for a more transparent view of the concept:
#!/bin/bash
#The primary array
bd_bands=(artcell rockStrata warfaze)
#inserting elements into the array at different positions
bd_bands[4]=vibe
bd_bands[10]=powersurge
# loop through the indices and print elements
for position in ${!bd_bands[@]};
do
echo "band ${bd_bands[$position]} is at index: $position"
done
echo "Hence, the currently busy indices are: ${!bd_bands[@]"
In this script, after defining the array bd_bands with 3 elements [positioned at index 0,1, 2 respectively.], I inserted 2 more elements into that array at positions 4 and 10. Then, exploiting the for loop, I displayed the elements along with their indices. This is visible that the elements are embedded with no issues at the assigned indices. The last line of the code also shows the index numbers that are currently reserved.
Here, I have used this script and inserted elements into random positions (indices 4 and 10) of the bd_bands array.
C. Update Array Elements in Bash
After the declaration of an array with elements, you may want to change the content of the extant array. Well, this is very simple to do using the array index numbers. The syntax of the code is given below:
example_array[index]=updated element
- example_array: The array that you want to update.
- index: The element you intend to update.
- updated element: The new value for assignment at the specific index.
To discern the updating concept, just follow the following script:
#!/bin/bash
#The actual array
topGun=(call sign ROOSTER)
#print the array
echo "before updation: ${topGun[@]}"
#update the array
topGun[2]=MAVERICK
#print the array with updated elements at index 2
echo "after updation: ${topGun[@]}"
The above bash script is an exemplar of the array updation operation. Here, I created an array with three values. Then, in line 7, I used the index assignment concept and updated the third value (index 2) of the array (replaced ROOSTER with MAVERICK). Finally, I used the echo command twice to display the changes.
The aforestated bash script updates the value ROOSTER with MAVERICK in the topGun array.
D. Remove Elements From Arrays in Bash
You can delete any array element that seems useless to you. The unset command in Bash lets you do it with no extra effort. In this section, I will talk about element removal for an array in Bash.
The standard syntax for deleting an element from an array is as follows:
unset example_array[index]
- unset: The bash command that deletes an array item of a specified index.
- example_array: The array from which you want to remove items.
- [index]: The index of the element that you will remove.
Let’s harness the deletion basics through an example:
#!/bin/bash
# the array
brands=(adidas puma nike)
#print array
echo "before removal: ${brands[@]}"
# Deleting nike from the array
unset brands[2]
#printing the array after removal of the element nike
echo "after removal: ${brands[@]}"
In the script, after the declaration of an array called brands with 3 elements, I used the unset command followed by the rest of the standard syntax (brands[2]) to remove the third element nike. After printing the array, you can see that I have successfully deleted the element.
Here, I have removed the item nike from the array brands using the unset command.
E. Slicing an Array in Bash
If you require to access certain elements from a long bash array, you can employ the concept of Array Slicing. To slice a bash array from a specific position up to a certain ending index, use the below syntax:
${array_name[@]:X:Y}
- array_name: The array name you want to assign.
- X: The beginning of the slice of the array.
- Y: The number of elements to slice starting from X.
At this point, I will run a bash script that takes an array and prints elements using the slicing technique. Just check the following script:
#!/bin/bash
#the actual array
food=(pizza burger sandwich hotdog pasta chicken)
#print the array
echo "original elements: ${food[@]}"
#slicing the array
sliced=${food[@]:2:3}
#printing the sliced elements
echo "sliced elements: $sliced"
The script takes an array named food which has 6 elements. Then, the slicing expression is defined and assigned to a variable called sliced. Using the formula, the script takes 3 elements ( sandwich, hotdog, pasta) starting the slicing from index 2. Finally, the echo command displays the sliced contents to the command prompt.
So, executing this script, I have only printed 3 items out of 6 items using the slicing technique.
F. Merging Two Bash Arrays
Sometimes you may need to add an array to some other bash array to accomplish your final goal. You can effortlessly do this by merging the two arrays using the expansion operator ${array[@]}. Remember to separate the arrays by space (More in the following script) for a successful amalgamation.
The typical syntax is as follows:
merged_array=(${array1[@]} ${array2[@]})
Now, let’s dive deeper through a practical illustration below:
#!/bin/bash
#The two arrays to be combined
movie1=(Inception Insomnia Prestige)
movie2 =(Dunkirk Tenet Oppenheimer)
#The merge of arrays
merged_array=(${movie1[@]} ${movie2[@]})
#print the seperate arrays
echo "movie1: ${merged_array[@]}"
echo "movie2: ${merged_array[@]}"
#print the merged array
echo "merged_array: ${merged_array[@]}"
The above script merges the two arrays namely movie1 and movie2 using the ${array[@]}
Expansion Operator where the array is the name of the arrays you want to merge separated by space. Finally, the merged_array verifies the addition of the two arrays.
Here, I have merged two arrays to create a new array called merged_array and printed all the contents at once.
Note: Don’t forget to use space between the arrays while merging to achieve a more readable format.
Code:
merged_array=(${movie1[@]} ${movie2[@]})
merged_no_space=(${movie1[@]}${movie2[@]})
Output:
4 Practical Examples of Using Arrays in Bash Scripts
The agenda of the previous features primarily revolved around the basics of the array structure in Bash involving quintessential concepts. Now that you have an ample grasp on bash arrays, Let’s look at a few examples to strengthen your understanding by going into more detail on the uses of bash arrays.
Example 01: Reading a File Through Bash Array
You may need to read the contents of a file using an array for data organization, and data processing purposes depending on the application. For instance, I will now create a file named lines.txt and access its contents using a bash array.
To read the file using an array, follow the below-mentioned bash script:
#!/bin/bash
echo “Enter the file_name you want to read”
read file # takes the file name as input from the user
array_of_file=( $(cat $file) ) # file contents are now assigned as array elements
#read the contents from the array
echo “the content of the file: $array_of_file[@]”
This bash script, first, takes the file name from user input and stores the content in the file variable defined after the read command in the 3rd line (read file). Then, the script accesses the contents using the cat command and saves them as array elements in the array namely array_of_file, and prints the elements using the expression $array_of_file[@].
In the above bash script, I have taken the contents of the file named poem.txt into an array and used the echo command in the script to print the contents as the elements of the array.
Example 02: Bubble Sorting in Bash Arrays
For the efficient retrieval and analysis of data, sorting is useful in programming. Likewise, sorted arrays in bash provide the smooth functionality of algorithms such as database, and searching algorithms. In this example, you will see the implementation of bubble sort in bash.
Bubble sorting is the easiest of all the sorting algorithms to understand. Bubble sorting operates by the comparison-based approach. It compares each adjacent element and swaps if they are in the wrong order until the entire is in the intended order (either ascending or descending).
To implement the bubble sort algorithm on the bash array follow this bash script:
#!/bin/bash
# The unsorted array
numbers=(2 3 1 5 4)
# array length
len=${#numbers[@]}
#print the unsorted array
echo “unsorted array: ${numbers[@]}”
#accessing elements of the array
for ((i=0; i<len; i++))
do
#comparing & swapping array elements
for ((j=0;j<len-i-1; j++))
do
if [ ${numbers[j]} -gt ${numbers[$((j+1))]} ]
then
temp=${numbers[j]}
numbers[$j]=${numbers[$((j+1))]}
number[$((j+1))]=$temp
fi
done
done
#print the sorted array
echo “sorted array: ${numbers[@]}”
First, the script takes an unsorted array and loops through the array length. In the iteration processes, the current element ${numbers[j]}
is compared to the next element ${numbers[$((j+1))]}
and swapped, in case, the previous element is larger than the latter one. The algorithm repeats the process until all the elements are sorted and placed into their respective positions. Finally, the echo command displays the sorted array to the terminal.
The script example2.sh sorts the above array using the bubble sort algorithm.
Example 03: Linear Search in Bash Arrays
You can search for a specific element in an array by implementing search algorithms. In this example, I will discuss the simplest one, the linear searching algorithm. It maintains a sequential searching technique by iterating through the array and checking if that desired element is present.
To take an array and find specific items using the linear search algorithm, see the below Bash script:
#!/bin/bash
#the array
array=(1 2 4 5 7)
#print the array
echo “the array: ${array[@]}”
# array length
len=${#array[@]}
# taking user input the element to search for
echo “enter the element to search”
read item
flag=0 # initializing a variable to track the desired element
# loop through the array and locate the element
for ((i=0; i<len; i++))
do
if [ ${array[$i]} -eq $item ]; then
echo “the item ${array[$i]} is at position $i”
flag=1 # indicates that the item is found
break # exit the loop immediately as the item is already found
fi
done
#if not found then alert
if [ $flag -eq 0 ]; then
echo “the item is not present in the array”
fi
The script takes an array and the element that it will search from the user input afterward. Then, it loops through the length of the array. During the looping process, the script checks if the current element array[$i] matches the item entered by the user.In addition, a flag (initialized to 0) variable tracks if the item is present in the array (0 if not found; 1 if found).
Now, if the item is present in the array, the echo command prints its location, the flag is set to 1 and the break statement immediately cancels the further iterations. After the loop, the script checks for the value of the flag variable and if it’s still 0, then it means that the array does not contain the item. So, it prints a message according to that.
The script returns the index of 2 since it’s present in the array. However, 8 is not an element of the array and, thus the message prints that “the item is not present in the array”.
Example 04: Multidimensional Arrays in Bash
Bash primarily supports one-dimensional arrays and it does not have anything like multi-dimensional arrays. However, multidimensional arrays can be simulated using the for loops in the bash script.
Here, the following script will display the simulation of a multidimensional array in Bash:
#!/bin/bash
# array declaration with no elements
declare -a matrices
#array dimension user input
echo “enter the number of rows:”
read row
echo “enter the number of columns:”
read cols
#looping through the rows and columns
for ((x=0; x<row; x++))
do
for ((y=0; y<cols; y++))
do
matrices[“$x, $y”]=$RANDOM # assigning random numbers to each position of the array
done
done
#print the multidimensional array
for ((x=0; x<row: x++))
do
for ((y=0: y<cols;y++))
do
echo -ne “${matrices[$x, $y]}\t”
done
echo # prints each row in a new line according to the user input dimensions
done
In the aforementioned script, I declared an empty array and named it matrices. Then, I used the read command to take user input on the dimension of the array. After that, I used two for loops for taking input of the matrice elements. The first loop iterates through each row and the second loop iterates through each column. Also, I also assigned random numbers here for each place in the matrics using $RANDOM. Finally, I used the for loop again to print the matrics to the screen for display.
The above bash script prints a multidimensional array with 2 rows and 3 columns.
Conclusion
In this article, I have provided you with an in-depth discussion on Bash arrays which are very powerful and versatile tools in the era of Bash scripting. Besides, I have attached hands-on illustrations for a comprehensive view of this topic because understanding working with arrays will immensely elevate your capability as a quality bash scripter. Summing up, I strongly believe that going through this article will take you a level further in the realm of bash programming.
People Also Ask
How to declare Array in Bash?
To declare an array in Bash, use the syntax declare -a array_name
. This declares an indexed array called array_name. Moreover, the syntax array_name=()
is also used to declare an indexed array. In addition, use the syntax declare -A assoc_array
to declare an associative array in Bash.
Are Bash arrays 0-based?
Yes, bash indexed arrays are 0-based. This means that the first item assignment starts from zero and increases by 1 after every insertion of elements. However, you can also insert elements at any specified index you want.
Does Bash have 2D arrays?
No, Bash does not come up with built-in 2D arrays. It only supports one-dimensional arrays. However, you can create arrays using multiple indices (associative arrays, array of arrays, etc.) but these are not true 2D arrays.
How to print a Bash array?
To print the Bash array, use the syntax echo ${array[@]} to print the array to the terminal. For example, to print the array digit=(1 2 3 4 5)
, the syntax will be echo ${digit[@]}
.
Can I get the length of an array in Bash?
Yes. To get the length of an array use the length expression syntax ${#array[@]} with the echo command. The prefix, #, here, tells the expression to return the array length instead of the array elements. For instance, to print length of the array, num=(11 12 13)
, the syntax is: echo ${#num[@]}
.
How do I create an array in Bash?
To create a bash array, you can use the “declare -a” command followed by the array name. Then, you can assign values to the array.
Is it possible to update an existing element of an array on Bash?
Absolutely. To update an existing element within a Bash array, simply access the element by its index and assign a new value to it using the syntax array[index]=new_value. For instance, to update the element banana of the array fruit=(apple banana pie)
with orange, the syntax would be fruit[1]=orange
.
Can I print the length of an individual element of a Bash array?
Yes, you can. To print the length of a specific element of a Bash array, use the length expression syntax ${#array[@]} but replace @ with the index of that element to print its length instead of the entire array. For example, to print the length of the element diamond of the array cards=(hearts diamonds spades clubs)
, use the code: echo ${#cards[1]}
. This will count the number of characters within that element diamond (including whitespaces) and return 8 as output.
Can I create a Bash associative array without the declare -A command?
No. To create an associative array in Bash, it is a must to use the declare
command with the -A
option. The -A flag tells Bash to create an associative array. Otherwise, Bash will treat the array as an indexed array by default. For example, the syntax declare -a array
creates an indexed array but the syntax declare -A array
will create an associative array.
Related Articles
- Declare Array in Bash [Create, Initialize]
- How to Read into Bash Array [3 Methods]
- Index Array in Bash [Explained]
- Bash Associative Arrays [Explained]
- Bash Array of Arrays [Explained]
- Elements of Bash Array
- How to Print an Array in Bash? [5 Methods]
- How to Get the Length of an Array in Bash?[Complete Guide]
- Array Operations in Bash
<< Go Back to Bash Scripting Tutorial
FUNDAMENTALS A Complete Guide for Beginners