my goal is to store each foliated line (actually each rule) into an array. My output:Chain INPUT (policy ACCEPT)num  target     prot opt source               destination         1    ACCEPT     udp  --  109.224.241.0/24     0.0.0.0/0            udp dpt:50602    ACCEPT     udp  --  109.224.241.0/24     0.0.0.0/0            udp dpt:45693    ACCEPT     udp  --  217.14.138.0/24      0.0.0.0/0            udp dpt:50604    ACCEPT     udp  --  217.14.138.0/24      0.0.0.0/0            udp dpt:45695    ACCEPT     udp  --  172.30.33.0/24       0.0.0.0/0            udp dpt:50606    ACCEPT     udp  --  172.30.33.0/24       0.0.0.0/0            udp dpt:45697    ACCEPT     udp  --  212.11.91.0/24       0.0.0.0/0            udp dpt:50608    ACCEPT     udp  --  212.11.91.0/24       0.0.0.0/0            udp dpt:45699    ACCEPT     udp  --  212.11.64.0/19       0.0.0.0/0            udp dpt:506010   ACCEPT     udp  --  212.11.64.0/19       0.0.0.0/0            udp dpt:456911   ACCEPT     udp  --  77.240.48.0/20       0.0.0.0/0            udp dpt:506012   ACCEPT     udp  --  77.240.48.0/20       0.0.0.0/0            udp dpt:456913   LOG        udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:4569 LOG flags 0 level 4 prefix AsteriskHack:14   DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:456915   LOG        udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:5060 LOG flags 0 level 4 prefix AsteriskHack:16   DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:5060Chain FORWARD (policy ACCEPT)num  target     prot opt source               destination         Chain OUTPUT (policy ACCEPT)num  target     prot opt source               destinationI do not want to limit rule number. Each chains has several rules.After I executed my code.:while IFS='' read line -r || [[ -n $line ]]; do     array+=($line)done < <(iptables -L --line-numbers)When I echo ${array[@]} my output is horrible text in one line, so I would like to seperate each line. Actually my content of this array consists of unreal number of iptables rules (after echo ${!array[@]})I do not know how to have in conditional that foliated rows are compulsory with defined separator (new line). I am not sure if is my separator right.Thank you for your reply,M
Read each line - BASH
bash;text processing
Here's how I'd do it. First, for simplicity, let's list each of the chains individually, since I'm assuming you want to know which chain a rule belongs to:$ iptables -L INPUT --line-numbersChain INPUT (policy ACCEPT)num  target     prot opt source               destination1    ACCEPT     udp  --  109.224.241.0/24     0.0.0.0/0            udp dpt:50602    ACCEPT     udp  --  109.224.241.0/24     0.0.0.0/0            udp dpt:45693    ACCEPT     udp  --  217.14.138.0/24      0.0.0.0/0            udp dpt:50604    ACCEPT     udp  --  217.14.138.0/24      0.0.0.0/0            udp dpt:45695    ACCEPT     udp  --  172.30.33.0/24       0.0.0.0/0            udp dpt:50606    ACCEPT     udp  --  172.30.33.0/24       0.0.0.0/0            udp dpt:45697    ACCEPT     udp  --  212.11.91.0/24       0.0.0.0/0            udp dpt:50608    ACCEPT     udp  --  212.11.91.0/24       0.0.0.0/0            udp dpt:45699    ACCEPT     udp  --  212.11.64.0/19       0.0.0.0/0            udp dpt:506010   ACCEPT     udp  --  212.11.64.0/19       0.0.0.0/0            udp dpt:456911   ACCEPT     udp  --  77.240.48.0/20       0.0.0.0/0            udp dpt:506012   ACCEPT     udp  --  77.240.48.0/20       0.0.0.0/0            udp dpt:456913   LOG        udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:4569 LOG flags 0 level 4 prefix AsteriskHack:14   DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:456915   LOG        udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:5060 LOG flags 0 level 4 prefix AsteriskHack:16   DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:5060You can get an list of chain names like this:CHAINS=$(iptables -L | awk '/Chain /{print $2}')Now, let's use a few tricks to simply get these into an array:# We can just define the array from the contents of our command# output, using \r or \n as a field separator.# We use grep to ignore lines that don't start with a number.IFS=$'\r\n' GLOBIGNORE='*' command eval 'INPUT_RULES=($(iptables -L INPUT --line-numbers | grep '^[0-9]'))'With Bash 4, you can also use the mapfile builtin:IFS=$'\r\n' mapfile INPUT_RULES < <(iptables -L INPUT --line-numbers | grep '^[0-9]')Now, I don't know your specific use case, but if you query each chain one at a time, you should also be able to remove the line numbers or use them as keys in an associative array, but maybe they're fine being included.If you don't want to use grep, but still want to exclude the first two lines from the array, you can just unset the first two elements after the fact, like this:array=(${array[@]:2})Also note that in your original example:echo ${array[@]}will put everything on one line whether it's in separate array keys or not. A better way to accurately view the array with one element per line, would be this:for rule in ${array[@]}; do echo LINE: $rule; done