Проблемы, подозрительные фрагменты:
$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
(и сопоставляет строки любым способом).