#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. Я немного обновил свою цель, пожалуйста, смотрите выше. Спасибо.