104 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
categories:
 | 
						|
  - Programming Languages
 | 
						|
tags:
 | 
						|
  - shell
 | 
						|
---
 | 
						|
 | 
						|
# Splitting input into an array
 | 
						|
 | 
						|
## readarray
 | 
						|
 | 
						|
`readarray` makes it really easy to split input into an array based on new
 | 
						|
lines. Say we have this file as input:
 | 
						|
 | 
						|
```
 | 
						|
123
 | 
						|
456
 | 
						|
789
 | 
						|
```
 | 
						|
 | 
						|
Then we can split like so:
 | 
						|
 | 
						|
```bash
 | 
						|
readarray -t name_for_array < ./input.text
 | 
						|
 | 
						|
# Print all elements
 | 
						|
echo "${name_for_array[@]}"
 | 
						|
 | 
						|
# Print element by index
 | 
						|
 | 
						|
echo "${name_for_array[1]}"
 | 
						|
456
 | 
						|
```
 | 
						|
 | 
						|
If we want to read a string directly:
 | 
						|
 | 
						|
```bash
 | 
						|
readarray -t new_name_for_array <<< "here
 | 
						|
is
 | 
						|
some
 | 
						|
text"
 | 
						|
 | 
						|
echo "${new_name_for_array[1]}"
 | 
						|
is
 | 
						|
```
 | 
						|
 | 
						|
> The _-t_ flag removes the trailing newline
 | 
						|
 | 
						|
See more: https://linuxhint.com/split-string-array-bash/
 | 
						|
 | 
						|
## read
 | 
						|
 | 
						|
For delimiters other than a space we have to use `read`, combined with `IFS` the
 | 
						|
**Internal Field Separator**.
 | 
						|
 | 
						|
For example, to split by comma:
 | 
						|
 | 
						|
```plaintext
 | 
						|
# comma-input.txt
 | 
						|
something,something else,something more
 | 
						|
```
 | 
						|
 | 
						|
```bash
 | 
						|
IFS=',' read -a arr < ./comma_inputs.txt
 | 
						|
```
 | 
						|
 | 
						|
> We use the `-a` flag to signal that we want each item read returned as an
 | 
						|
> element in an array
 | 
						|
 | 
						|
## mapfile
 | 
						|
 | 
						|
We can use `mapfile` to read the lines of a input file in set segments.
 | 
						|
 | 
						|
For the following file:
 | 
						|
 | 
						|
```
 | 
						|
line one
 | 
						|
line two
 | 
						|
line three
 | 
						|
line four
 | 
						|
```
 | 
						|
 | 
						|
We could generate the following output:
 | 
						|
 | 
						|
```
 | 
						|
-----SNIP-----
 | 
						|
line one
 | 
						|
line two
 | 
						|
-----SNIP-----
 | 
						|
line three
 | 
						|
line four
 | 
						|
```
 | 
						|
 | 
						|
With:
 | 
						|
 | 
						|
```bash
 | 
						|
while mapfile -t -n 2 ary && ((${#ary[@]})); do
 | 
						|
  printf '%s\n' "${ary[@]}"
 | 
						|
  printf -- '--- SNIP ---\n'
 | 
						|
 done < $testInput
 | 
						|
```
 | 
						|
 | 
						|
So, while there are input lines, map each line into an array and return it in
 | 
						|
groups of 2.
 |