Доступ к переменным, имеющим целое число внутри имени - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь выполнить некоторые операции (например, добавление столбцов) с двумя наборами файлов (несколько больших файлов). Два набора идентичны по количеству файлов, а также по формату данных внутри файлов.

  set1:          set2:
  fileA          fileX
  fileB          fileY
  fileC          fileZ


  cat fileA
  1
  2
  cat fileX
  5
  6

Я пытаюсь добавить их столбцы

 paste fileA fileX > tmpA
 awk '{print $1+$2}' tmpA > output1

 paste fileB fileY > tmpB
 awk '{print $1+$2}' tmpB > output2

Я хочу сделать эту операцию с циклом for. Так как файлы не идентифицированы ни одним из чисел в имени файла, я пытаюсь сделать следующее:

f1=dir1/fileA
f2=dir1/fileB
f3=dir1/fileC

g1=dir2/fileX
g2=dir2/fileY
g3=dir2/fileZ

for i in `seq 1 3`
do
paste $f$i $g$i > tmp
awk '{print $1+$2}' tmp > output$i
rm tmp
done

Мой вопрос: есть ли способ определить $f$i как $f1,$f2,$f3 переменные, назначенные файлам?

Большое спасибо.

Ответы [ 2 ]

2 голосов
/ 21 июня 2019

Я предлагаю использовать два массива, которые вы будете повторять одновременно:

f_files=(dir1/fileA dir1/fileB dir1/fileC) # or shorter :  =(dir1/file{A,B,C})
g_files=(dir2/fileX dir2/fileY dir2/fileZ) # or shorter :  =(dir2/file{X,Y,Z})

for ((i=0; i<${#f_files[@]}; i++)); do
    paste ${f_file[$i]} ${g_files[$i]} > tmp
    awk '{print $1+$2}' tmp > output$i
    rm tmp
done

Я основал количество итераций на длине массива f_files, но учтите, что он начинается с 0, поскольку массивы индексируются с 0, что влияет на имена выходных файлов. Очевидно, это можно исправить с помощью небольшой арифметики, если это будет необходимо.

Я предлагаю также удалить промежуточный файл tmp (paste ${f_file[$i]} ${g_files[$i]} | awk ...) или, по крайней мере, удалить его только после окончания цикла, поскольку > перезаписывает содержимое файла.

1 голос
/ 21 июня 2019

Мне очень нравится ответ @Aaron.Я просто предлагаю включить команду paste в команду awk.Так что в конечном итоге это выглядит так:

f_files=(dir1/fileA dir1/fileB dir1/fileC) # or shorter :  =(dir1/file{A,B,C})
g_files=(dir2/fileX dir2/fileY dir2/fileZ) # or shorter :  =(dir2/file{X,Y,Z})

for i in $(seq 0 ${#f_files[@]}); do
    awk 'NR==FNR{inp1[NR]=$1; next;} {print($1+inp1[FNR])}' "${f_files[i]}" "${g_files[i]}" > output$i
done

Я добавил кавычки вокруг "${f_files[i]}" и "${g_files[i]}", на случай, если в имени файла есть пробелы.

...