Проблемы, подозрительные фрагменты:
$matched_file_id содержит ноль или более значений, сравнение с $FILE_ID успешно выполняется только при наличии одного значения;
$matched_file_id устанавливается один раз для каждой line , сравнение с $FILE_ID выполняется один раз для FILE_ID ;
- в конце
done лишнее (?);
column values должны принадлежать комментарию;
- переменные не заключены в кавычки;
TMP должен быть установлен.
Это переписанная процедура. Это не совсем эквивалентно, но подход кажется лучше:
TMP="/the/right/path"
find . -type f -name '*CDI*.dat' \
-exec sh -c '
<"$1" cut -f3 -d"|" | grep -qFx -f "$TMP/TempBatchData.txt"
' sh {} \; -print > final_cdi_list.txt
Объяснение:
find находит все файлы, соответствующие шаблону *CDI*.dat .
- Для каждого такого файла запускается оболочка для обработки канала.
cut экстракты третьего столбца.
grep спокойно (-q) проверяет, существует ли какая-либо буквальная строка (-F) из данного файла (-f) в выходных данных cut как целая строка (-x).
- Если это так, команда
find распечатает путь к файлу.
Примечания, отличия, причуды:
find действия рекурсивно. Чтобы обработать только текущий каталог без подкаталогов, вам нужно -maxdepth 1 (не требуется POSIX) или решение POSIX из этого вопроса, или позволить оболочке развернуть *CDI*.dat (find *CDI*.dat -type f -exec …) у которого есть свои минусы.
find напечатает пути с ведущими ./ . Для получения базовых имен вам нужно -printf '%f\n' (не POSIX) вместо -print или, например, -exec basename {} \; (Соответствует POSIX) вместо -print .
grep -F соответствует буквенным строкам. В вашем коде каждая строка из $TMP/TempBatchData.txt дважды подвергается неявной обработке:
- с
read FILE_ID (в отличие от read -r FILE_ID),
- внутри
[[ $matched_file_id == $FILE_ID ]] (сравнение с использованием [[ выполнить сопоставление с шаблоном по строке без кавычек справа, а не просто по сравнению с простой строкой).
Я не уверен, если вы полагаетесь на это. Вы можете настроить мой код.
В заголовке упоминается копирование файлов в другой каталог. При моем подходе вам не нужно обрабатывать final_cdi_list.txt для этого. Просто используйте -exec cp {} "/another/directory" \; вместо -print .
Всю работу по поиску подходящих файлов можно выполнить с помощью единственного grep , однако вам необходимо настроить шаблон. Пример:
grep -l '^[0-9]*|[0-9]*|840920|' *CDI*.dat
В файле может быть много шаблонов (-f "$TMP/TempBatchData.txt"), но они должны быть такими же, как указано выше. Если существует слишком много файлов, соответствующих *CDI*.dat вы получите "список аргументов слишком длинный" (подход с параметром for file in *CDI*.dat; вы изначально использовали, защищен от этого).
Возможно, измените структуру каталогов (например, только файлы *CDI*.dat в текущем каталоге и подкаталогах, разрешен рекурсивный поиск или нет подкаталогов вообще) и формат файла шаблона. Идея состоит в том, чтобы использовать
grep -lr -f "$TMP/TempBatchData.txt"
или что-то подобное. Обратите внимание, что -r не требуется для POSIX, в этом примере его значение взято из GNU grep: рекурсивно читать все файлы в текущем рабочем каталоге.
Один процесс grep должен быть быстрее любого решения, которое использует find -exec или read (и сопоставляет строки любым способом).