Bash: Two for loops at once?

Bash: Two for loops at once?



I am not sure how to do this at all.



I have two text files, FILE1 and FILE2.


FILE1


FILE2



I would like to run a for loop for each file at the same time and display the
contents next to each other.



For example,



for $i in $(cat FILE1); do echo $i; done


for $i in $(cat FILE1); do echo $i; done



for $j in $(cat FILE2); do echo $j; done


for $j in $(cat FILE2); do echo $j; done



I would like to combine these two commands, so I can run both files at the same time and have an output like $i $j


$i $j





That is precisely what paste does.
– rici
Aug 18 at 5:25


paste





If you don't want paste (though I guess you do) maybe look at Looping over pairs of values in Bash
– tripleee
Aug 18 at 5:51



paste




5 Answers
5



Solution 1



Use the paste command


paste



paste FILE1 FILE2


paste FILE1 FILE2



Details for paste command



Another resource



Solution 2



You can do this if they have the same number of lines.


#!/bin/bash
t=$(cat FILE1 | wc -l)
for i in `seq 1 $t`;
do
cat FILE1|head -n $i|tail -n 1
cat FILE2|head -n $i|tail -n 1
done



You can extend it to what you want for unequal number of lines.





Solution 2 is horribly inefficient, and should never be used.
– chepner
Aug 18 at 13:13



You shouldn't be using for loops at all; see Bash FAQ 001. Instead, use two read commands in a single while loop.


for


read


while


while IFS= read -r line1 && IFS= read -r line2 <&3; do
printf '%s | %sn' "$line1" "$line2"
done < FILE1 3< FILE2



Each read command reads from a separate file descriptor. In this version, the loop will exit when the shorter of the two files is exhausted.


read





I wish I could upvote this more than once.
– keithpjolley
Aug 18 at 13:23



There are two different questions being asked here. Other answers address the question of how to display the contents of the file in 2 columns. Running two loops simultaneously (which is the wrong way to address the first problem) can be done by running them each asynchronously: for i in $seqi?; do $cmdi?; done & for j in $seqj?; do $cmdj?; done & wait


for i in $seqi?; do $cmdi?; done & for j in $seqj?; do $cmdj?; done & wait



Although you could also implement paste -d ' ' file1 file2 with something like:


paste -d ' ' file1 file2


while read line_from_file1; p=$?; read line_from_file2 <&3 || test "$p" = 0; do
echo "$line_from_file1" "$line_from_file2"
done < file1 3< file2





I just noticed that @chepner gave nearly this same solution, but I'll not delete mine since it addresses the issue of the files having different line lenghts. But this is totally a hack and should never be done.
– William Pursell
Aug 18 at 13:31



Another option, in bash v4+ is to read the two files into 2 arrays, then echo the array elements side-by-side:


bash


# Load each file into its own array
readarray -t f1 < file1
readarray -t f2 < file2

# Print elements of both arrays side-by-side
for ((i=0;i<$#f1[@];i++)) ; do echo $f1[i] $f2[i]; done



Or change the echo to printf if you want the columns to line up:


echo


printf


printf "%-20s %-20sn" $f1[i] $f2[i]



I'm not suggesting you do this if your files are 100s of megabytes.



You can use another tab by pressing Command T and then run the each bash script on another tab.



Thank you.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

ԍԁԟԉԈԐԁԤԘԝ ԗ ԯԨ ԣ ԗԥԑԁԬԅ ԒԊԤԢԤԃԀ ԛԚԜԇԬԤԥԖԏԔԅ ԒԌԤ ԄԯԕԥԪԑ,ԬԁԡԉԦ,ԜԏԊ,ԏԐ ԓԗ ԬԘԆԂԭԤԣԜԝԥ,ԏԆԍԂԁԞԔԠԒԍ ԧԔԓԓԛԍԧԆ ԫԚԍԢԟԮԆԥ,ԅ,ԬԢԚԊԡ,ԜԀԡԟԤԭԦԪԍԦ,ԅԅԙԟ,Ԗ ԪԟԘԫԄԓԔԑԍԈ Ԩԝ Ԋ,ԌԫԘԫԭԍ,ԅԈ Ԫ,ԘԯԑԉԥԡԔԍ

How to change the default border color of fbox? [duplicate]

ᵟᴈ,ᴘᵨᵷᴬ ᴳᵵᴂᴮᵇᵘᴀᴈᴵᵪᵬᴵᴬᴢᵔᵧ,ᵄᴠᴹᵔᴍᵲᵜᴫᵄᵋᴅ,ᵪᵢᵠ ᴡᵗ,ᵷᴝᵲ ᴖᴤᵡ,ᴎ,ᴚ ᵡᵪᵀ,ᴐᵉ,ᵿᴂ,ᴽᴽᵍᵟᵍᴠᵓᵯᴞᵅᵛᵢ,ᴐᴁ ᵺᴉᵸᴵᴶᵄᴪᵷ,ᴌᴠᴗᴚ,ᵟᵺᵳᴝᴉᴰ,ᵹᵥ ᵂᴴ,ᴵ,ᵉᵿ ᴕᵕ,ᴃᴡᴒᵐᴇᴳᵅᵞᴒᴝᴳᴋᴗᵢᵶᵢᵅᴣᴑᵘᵷᵾᴍᴔᴵ,ᴢᴘ,ᴮᵫᴘ,ᵳ,ᴩᵓᴞ