Проблемы, подозрительные фрагменты:
$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
quietly (-q
) проверяет, существует ли какая-либо буквальная строка (-F
) из данного файла (-f
) в выходных данныхcut
как целая строка (-x
).- Если это так,
find
будет напечатан путь к файлу.
Примечания, отличия, причуды:
find
действует рекурсивно. Чтобы обработать только текущий каталог без подкаталогов, в которых вы нуждаетесь-maxdepth 1
(не требуется POSIX) или POSIX-решение из этого вопроса, или позволить shell расширить*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
(и сопоставляет строки любым способом).