Is there a way to specify multiple variables (not just integers) in for loops in bash? I may have 2 files containing arbitrary text that i would need to work with.What i functionally need is something like this:for i in $(cat file1) and j in $(cat file2); do command $i $j; doneAny ideas?
Multivariable For Loops
bash;command substitution;for
First, Don't read lines with for, as there are several unavoidable issues with reading lines via word-splitting.Assuming files of equal length, or if you want to only loop until the shorter of two files are read, a simple solution is possible.while read -r x && read -r y <&3; do    ...done <file1 3<file2Putting together a more general solution is hard because of when read returns false and several other reasons. This example can read an arbitrary number of streams and return after either the shortest or longest input.#!/usr/bin/env bash# Open the given files and assign the resulting FDs to arrName.# openFDs arrname file1 [file2 ...]openFDs() {    local x y i arr=$1    [[ -v $arr ]] || return 1    shift    for x; do        { exec {y}<$x; } 2>/dev/null || return 1        printf -v ${arr}[i++] %d $y    done}# closeFDs FD1 [FD2 ...]closeFDs() {    local x    for x; do        exec {x}<&-    done}# Read one line from each of the given FDs and assign the output to arrName.# If the first argument is -l, returns false only when all FDs reach EOF.# readN [ -l ] arrName FD1 [FD2 ...]readN() {    if [[ $1 == -l ]]; then        local longest        shift    else        local longest=    fi    local i x y status arr=$1    [[ -v $arr ]] || return 1    shift    for x; do        if IFS= read -ru $x ${arr}[i] || { unset -v ${arr}[i]; [[ ${longest+_} ]] && return 1; }; then            status=0        fi        ((i++))    done    return ${status:-1}}# readLines file1 [file2 ...]readLines() {    local -a fds lines    trap 'closeFDs ${fds[@]}' RETURN    openFDs fds $@ || return 1    while readN -l lines ${fds[@]}; do        printf '%-1s ' ${lines[@]}        echo    done}{    readLines /dev/fd/{3..6} || { echo 'error occured' >&2; exit 1; }} <<<$'a\nb\nc\nd' 3<&0 <<<$'1\n2\n3\n4\n5' 4<&0 <<<$'x\ny\nz' 5<&0 <<<$'7\n8\n9\n10\n11\n12' 6<&0# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:So depending upon whether readN gets -l, the output is eithera 1 x 7b 2 y 8c 3 z 9d 4 105 1112ora 1 x 7b 2 y 8c 3 z 9Having to read multiple streams in a loop without saving everything into multiple arrays isn't all that common. If you just want to read arrays you should have a look at mapfile. 