I use the following for placing the lines of a file in an array:
IFS=$'\r\n' GLOBIGNORE='*' command eval 'array=($(<filename))'
This gets all the columns and you can later work with it.
Edit: Explanations on the procedure above:
- IFS=$'\r\n': stands for "internal field separator". It is used by the shell to determine how to do word splitting, i. e. how to recognize word boundaries.
- GLOBIGNORE='*': From the bash's manual page: A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches.
- command eval: The addition of command eval allows for the expression to be kept in the present execution environment
- array=...: Simply the definition.
There are different threads on Stackoverflow and Stackexchange with more details on this:
https://unix.stackexchange.com/questions/184863/what-is-the-meaning-of-ifs-n-in-bash-scripting
https://unix.stackexchange.com/questions/105465/how-does-globignore-work
Read lines from a file into a Bash array
Then I just loop around the array like this:
for (( b = 0; b < ${#array[@]}; b++ )); do
#Do Somethng
done
This could be matter of opinion. Please, wait for more comments.
Edit: Use case with empty lines and globs
After the comments yesterday. I finally have had time to test the suggestions (empty lines, lines with globs)
In both cases the array is working fine when working in conjunction with awk. In the following example I attempt to print only the column2 into a new text file:
IFS=$'\r\n' GLOBIGNORE='*' command eval 'array=($(<'$1'))'
for (( b = 0; b < ${#array[@]}; b++ )); do
echo "${array[b]}" | awk -F "/| " '{print $2}' >> column2.txt
done
Starting with the following text file:
290729 123456
79076 12345
76789 123456789
59462 password
49952 iloveyou
33291 princess
21725 1234567
20901 rockyou
20553 12345678
16648 abc123
20901 rockyou
20553 12345678
16648 abc123
/*/*/*/*/*/*
20901 rockyou
20553 12345678
16648 abc123
Clear empty lines and globs in the script.
The result of the execution is the following:
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
rockyou
12345678
abc123
*
rockyou
12345678
abc123
Clear evidence that the array is working as expected.
Execution example:
adama@galactica:~$ ./processing.sh test.txt
adama@galactica:~$ cat column2.txt
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
rockyou
12345678
abc123
*
rockyou
12345678
abc123
Should we wish to remove empty lines (as it doesn't make sence to me have them in the output) we can do it in awk by changing the following line:
echo "${array[b]}" | awk -F "/| " '{print $2}' >> column2.txt
adding /./
echo "${array[b]}" | awk -F "/| " '/./ {print $2}' >> column2.txt
End Result:
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
rockyou
12345678
abc123
*
rockyou
12345678
abc123
Should you wish to apply it to the whole file (not column by column) you can take a look at the following thread:
AWK remove blank lines
Edit: Security concern on rm:
I actually went ahead and placed $(rm -rf ~) in the test file to test what would happen on a virtual machine:
Test.txt contents now:
290729 123456
79076 12345
76789 123456789
59462 password
49952 iloveyou
33291 princess
21725 1234567
20901 rockyou
20553 12345678
16648 abc123
$(rm -rf ~)
20901 rockyou
20553 12345678
16648 abc123
/*/*/*/*/*/*
20901 rockyou
20553 12345678
16648 abc123
Execution:
adama@galactica:~$ ./processing.sh test.txt
adama@galactica:~$ ll
total 28
drwxr-xr-x 3 adama adama 4096 dic 1 22:41 ./
drwxr-xr-x 3 root root 4096 dic 1 19:27 ../
drwx------ 2 adama adama 4096 dic 1 22:38 .cache/
-rw-rw-r-- 1 adama adama 144 dic 1 22:41 column2.txt
-rwxr-xr-x 1 adama adama 182 dic 1 22:41 processing.sh*
-rw-r--r-- 1 adama adama 286 dic 1 22:39 test.txt
-rw------- 1 adama adama 1545 dic 1 22:39 .viminfo
adama@galactica:~$ cat column2.txt
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
-rf
rockyou
12345678
abc123
*
rockyou
12345678
abc123
No effect on the system.
Note: I am using Ubuntu 18.04 x64 LTS on an VM. Best not to try testing the security issue with root.
Edit: set -f
necessity:
adama@galactica:~$ ./processing.sh a
adama@galactica:~$ cat column2.txt
[a]
adama@galactica:~$
Works perfectly without set -f
BR