bash читает несколько файлов с помощью «во время чтения»

Когда у меня есть один текстовый файл, который я хочу читать построчно с помощью bash, команда выглядит так:

while IFS='' read -r line || [[ -n "${line}" ]];
do
    [code goes here]
done <(${filename})

Теперь у меня есть несколько файлов (с именами от 1.txt до 10.txt), все из которых имеют одинаковое количество строк (~ 1600). Обработка цикла while для каждого файла в отдельности занимает много времени, есть ли способ читать и обрабатывать все параллельно (т. е. все 10 файлов будут читаться одновременно, но обрабатываться отдельно) с синтаксисом while? Например:

While IFS='' read -r line || [[ -n "${line}" ]];
do
    [code goes here]
done <(1.txt; 2.txt; 3.txt; ...)

Или может быть лучший способ добиться желаемой обработки нескольких текстов, кроме создания для этого 10 отдельных сценариев?

Общая цель состоит в том, что файлы 1.txt - 10.txt состоят из ~ 1600 отдельных идентификаторов, в которых сначала будет раздел [код идет здесь]:

1) прочитать идентификатор построчно

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

3) На основе этой извлеченной информации о времени теперь мы создаем файлы на 1 час раньше и на 1 час позже с шагом в 2 минуты. Затем мы ссылаемся на каждый из этих 60 файлов, открываем их, затем извлекаем строку из этого файла и, наконец, выгружаем ее в новый файл.

Таким образом, процесс состоит из открытия нескольких разных файлов для ссылки.


person WX_M    schedule 08.08.2019    source источник
comment
Что на самом деле делает код здесь? Если он устанавливает переменные оболочки или иным образом изменяет состояние таким образом, чтобы оно сохранялось после завершения цикла, это сильно ограничивает возможности многопроцессорной обработки.   -  person Charles Duffy    schedule 08.08.2019
comment
... кроме того, для 1600 строк у вас должно быть очень мало накладных расходов от самого bash (недостаточно, чтобы оправдать накладные расходы на распараллеливание), что означает, что это то, что вы делаете в цикле, который медленный. Если вещи, которые в настоящее время разветвляют подоболочки, запускают конвейеры и т. д. можно перемещать в процессе, вся проблема может исчезнуть.   -  person Charles Duffy    schedule 08.08.2019
comment
Вы можете открыть каждый файл в отдельном файловом дескрипторе. Для файловых дескрипторов 3-9 это довольно просто. Однако документация рекомендует проявлять осторожность при работе с большими файловыми дескрипторами, которые могут использоваться внутри оболочки. Есть способ позволить оболочке выделить для вас доступный дескриптор, но в документации нет подробностей о том, как это сделать правильно. (В частности, я не уверен, что вы можете выделить и использовать дескриптор в одной и той же команде, и я не знаю, как правильно закрыть дескриптор впоследствии.)   -  person chepner    schedule 08.08.2019
comment
Re: открытие нескольких файлов для ссылок -- это похоже на работу для join. Вам нужно будет предварительно отсортировать файлы по ключам соединения, но делайте это правильно, и ваши поиски будут очень, очень быстрыми (и, что наиболее важно, вы сможете выполнять их все за один проход, вместо этого перечитывать файлы снова и снова).   -  person Charles Duffy    schedule 08.08.2019


Ответы (1)


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

например. если имя сценария — process_file.sh $./process_file.sh <file_name>

Вы можете разработать еще один сценарий поддержки, который имеет список файлов и циклов, вызывает этот сценарий и переводит его в фоновый режим, используя «&», например.

declare -a arr=("1.txt" "2.txt" "3.txt")

for i in "${arr[@]}"
do
    ./process_file.sh $i &
done

Это может быть один из подходов, который вы можете попробовать и проверить.

person koushikmln    schedule 08.08.2019