Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping over pairs of values in bash [duplicate]

I have 10 text files and I want to paste each file with its pair, such that I have 5 total files.

I tried the following:

for i in 4_1 5_1 6_1 7_1 8_1
do
for j in 4_2 5_2 6_2 7_2 8_2
do
paste ${i}.txt ${j}.txt > ${i}.${j}.txt
done
done

However, this code combines every possible combination instead of just combining the matching pairs.

So I would like file 4_1.txt to be paired with 4_2.txt, 5_1.txt with 5_2.txt, etc.

like image 449
Rish Avatar asked Feb 25 '15 17:02

Rish


4 Answers

I agree with the answer currently proposed by fedorqui in the context of the question currently asked. The below is given only to provide some more general answers.

One more general approach (for bash 4.0 or newer) is to store your pairs in an associative array:

declare -A pairs=( [4_1]=4_2 [5_1]=5_2 [6_1]=6_2 [7_1]=7_2 [8_1]=8_2 )
for i in "${!pairs[@]}"; do
  j=${pairs[$i]}
  paste "$i.txt" "$j.txt" >"${i}.${j}.txt"
done

Another (compatible with older releases of bash) is to use more than one conventional array:

is=( 4_1 5_1 6_1 7_1 8_1 )
js=( 4_2 5_2 6_2 7_2 8_2 )
for idx in "${!is[@]}"; do
  i=${is[$idx]}
  j=${js[$idx]}
  paste "$i.txt" "$j.txt" >"$i.$j.txt"
done
like image 96
Charles Duffy Avatar answered Nov 15 '22 05:11

Charles Duffy


Simplest so far:

for i in "1 a" "2 b" "3 c"; do a=( $i ); echo "${a[1]}"; echo "${a[0]}"; done

a
1
b
2
c
3
like image 32
Fibo Kowalsky Avatar answered Nov 15 '22 05:11

Fibo Kowalsky


You can use an associative array:

animals=(dog cat mouse)
declare -A size=(
  [dog]=big
  [cat]=medium
  [mouse]=small
)
declare -A sound=(
  [dog]=barks
  [cat]=purrs
  [mouse]=cheeps
)
for animal in "${animals[@]}"; do
  echo "$animal is ${size[$animal]} and it ${sound[$animal]}"
done

This allows you traversing pairs, triples, etc. Credits: the original idea is taken from @CharlesDuffy-s answer.

like image 27
VasiliNovikov Avatar answered Nov 15 '22 07:11

VasiliNovikov


If you want to use one variable and perform and action with it, you just need to use one loop:

for file in 4 5 6 7 8
do
   paste "${file}_1" "${file}_2"
done

This will do

paste 4_1 4_2
paste 5_1 5_2
...
like image 34
fedorqui 'SO stop harming' Avatar answered Nov 15 '22 07:11

fedorqui 'SO stop harming'