Можно ли использовать переменную, меняющую свое имя в цикле, в качестве входных данных для функции в сценарии оболочки?

#bash #shell #sh

#удар #оболочка #ш #bash #sh

Вопрос:

Мое намерение состоит в том, чтобы прочитать несколько файлов и записать данные в соответствующий массив. Затем массив будет дополнительно обработан. пример:

 #!/bin/sh

for i in 0 1 2 3 4 5
do
    set -A data$i
done

i=2
t=data$i

//read data from file into data2, data3 ...
read_file(){

ifile="/tmp/proc/test/2"   //should loop all files in the folder, file 2, 3, 4, ..., save to data2, data3, ....
j=1
for i in $( awk  -F ',' '{ print $1; }' "${ifile}" )
do
    t[$j]=$i
    echo "${t[$j]}" 
    j=$((j 1))
done
    echo "done read_file"
}

//intention to process data2, data3..., but not sure how to do it.
process_data(){
input=$1
  
#echo ${!$1}
 
#for line in "${!input[@]}"
#do
    #echo "test: "
    #eval "echo $$line"
    #echo ${!line}
        
#done
#}

#process $t

}

  

Возможно ли это сделать с помощью сценария оболочки (bash тоже в порядке)?
Есть ли другие способы сделать это?
Пожалуйста, любезно дайте свои предложения.
Спасибо.

Небольшое обновление о моей цели: я хочу прочитать файлы в папке, пометить все дубликаты и подсчитать количество дубликатов в файлах. Затем для каждого файла в папке укажите, сколько уникальных элементов, сколько повторяющихся элементов и время появления дубликатов.(дубликаты должны возникать только между файлами)

Мой оригинальный скрипт считывает все файлы в папке, используйте awk, чтобы получить все дубликаты и вхождения (сохранить в файл all_dup), затем сравните каждый файл с all_dup (используйте awk), укажите each_file_dup, each_file_uniq.

Я подумываю ускорить это, записывая данные в массив вместо файлов. Но не уверен, что это действительно работает. Файлы варьируются от сотен до тысяч строк (long int). Спасибо за любые предложения.

Комментарии:

1. Возможны динамические имена переменных (см. BashFAQ # 6 ), но, как правило, беспорядочно и легко ошибиться. Я бы рекомендовал попытаться реструктурировать ваш код, чтобы они не были нужны.

2. да, я думаю об этом, но пока не выдвигаю никаких хороших идей. Спасибо.

3. Может ли это быть XY Prolem ?

4. Пожалуйста, расширьте детали «получить все дубликаты». Вы имеете в виду дублирование внутри файла? Или между файлами? Если вы можете написать ЧЕТКИЕ спецификации, я уверен, что мы сможем придумать что-то быстрое и сравнительно простое или, по крайней мере, чистое. 🙂

5. Я думаю, вам было бы лучше написать это в чем-то другом, кроме bash; что-то с приличными структурами данных. Я бы предпочел Python, но есть много хороших вариантов. Сценарии оболочки хороши для указания другим программам выполнять сложные действия с данными, но плохо подходят для непосредственной работы со сложными и / или большими наборами данных.

Ответ №1:

Чтение нескольких файлов в один массив является тривиальным.

 arrayName=( $( cat file1 file2 $someGlob ) )
  

Если имена файлов также допустимы как имена массивов, вы можете использовать динамическую оценку.

 $: grep . ?
a:1
a:2
a:3
b:4
b:5
b:6
c:7
c:8
c:9

$: lst=(?)
$: set -x; for f in ${lst[@]}; do eval "$f=($(<$f))"; eval : "$f: ${${f}[@]}"; done; set  x
  for f in ${lst[@]}
  eval 'a=($(<a))'
   a=($(<a))
  eval : 'a: ${a[@]}'
   : a: 1 2 3
  for f in ${lst[@]}
  eval 'b=($(<b))'
   b=($(<b))
  eval : 'b: ${b[@]}'
   : b: 4 5 6
  for f in ${lst[@]}
  eval 'c=($(<c))'
   c=($(<c))
  eval : 'c: ${c[@]}'
   : c: 7 8 9
  

Лично я предпочитаю исходный временный файл.

 $: for f in ${lst[@]}; do echo "$f=($(<$f))">tmpfile; . tmpfile; done;
$: echo ${b[1]} 
5
  

Если все файлы имеют допустимые имена переменных в /tmp/proc/test/ , то вы могли бы использовать что-то вроде этого —

 flist=( /tmp/proc/test/* )
for f in "${flist[@]}"
do echo "${f//[/]/_}=($(<$f))" >| tmpfile; 
  . tmpfile; 
done
  

При этом будет использоваться имя _tmp_proc_test_2 массива для файла /tmp/proc/test/2 .

Комментарии:

1. Большое вам спасибо за ваш ответ. Я обязательно подумаю о редизайне. Ранее я также использовал временный файл для сохранения данных, но он оказывается медленным, поэтому я думаю, может быть, использовать переменную для ускорения.

2. Это зависит от того, что вы делаете с данными. Можете ли вы создать резервную копию и объяснить, что вы пытаетесь выполнить , а не проблему, которую вы видите при попытке нового метода?

3. Я немного обновил свою цель, пожалуйста, смотрите выше. Спасибо.