Des problèmes, des fragments suspects :
-
$matched_file_id
contient zéro ou plusieurs valeurs, la comparaison avec $FILE_ID
ne réussit que lorsqu'il y a une seule valeur ;
-
$matched_file_id
est défini une fois par line
par rapport à $FILE_ID
est effectuée une fois par FILE_ID
;
- il y a un supplément
done
à la fin ( ?);
-
column values
doit appartenir à un commentaire ;
- Les variables ne sont pas citées ;
-
TMP
doit être défini.
Il s'agit d'une procédure réécrite. Ce n'est pas complètement équivalent mais l'approche semble meilleure :
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
Explication :
-
find
trouve tous les fichiers correspondant à l'option *CDI*.dat
modèle.
- Pour chaque fichier de ce type, un Shell est exécuté pour traiter un tuyau.
-
cut
extrait la troisième colonne.
-
grep
tranquillement ( -q
) vérifie si une chaîne littérale ( -F
) à partir du fichier donné ( -f
) existe dans la sortie de cut
comme une ligne entière ( -x
).
- Si c'est le cas,
find
imprimera le chemin d'accès au fichier.
Notes, différences, bizarreries :
-
find
agit de manière récursive. Pour traiter uniquement le répertoire courant sans les sous-répertoires, vous avez besoin de -maxdepth 1
(non requis par POSIX) ou une solution POSIX de cette question ou laisser le Shell s'étendre. *CDI*.dat
( find *CDI*.dat -type f -exec …
) qui a ses inconvénients.
-
find
imprimera les chemins avec le premier ./
. Pour obtenir les noms de base, vous devez -printf '%f\n'
(non-POSIX) au lieu de -print
ou par exemple -exec basename {} \;
(conforme à POSIX) au lieu de -print
.
-
grep -F
correspond à des chaînes de caractères littérales. Dans votre code, chaque ligne de $TMP/TempBatchData.txt
subit deux fois un traitement implicite :
- avec
read FILE_ID
(par opposition à read -r FILE_ID
),
- à l'intérieur de la
[[ $matched_file_id == $FILE_ID ]]
(comparaisons utilisant [[
effectuer une comparaison de motifs avec la chaîne non citée du côté droit, et non une simple comparaison de chaînes de caractères).
Je ne sais pas si vous comptez sur ça. Vous pourriez vouloir ajuster mon code.
-
Le titre mentionne la copie de fichiers dans un autre répertoire. Avec mon approche vous n'avez pas besoin de traiter final_cdi_list.txt
pour le faire. Il suffit d'utiliser -exec cp {} "/another/directory" \;
au lieu de -print
.
Tout le travail de recherche de fichiers qui correspondent peut être fait avec une seule et unique. grep
Vous devez cependant ajuster le modèle. Par exemple :
grep -l '^[0-9]*|[0-9]*|840920|' *CDI*.dat
Vous pouvez avoir plusieurs motifs dans un fichier ( -f "$TMP/TempBatchData.txt"
) mais ils doivent être comme ceux mentionnés ci-dessus. S'il y a trop de fichiers correspondant *CDI*.dat
vous obtiendrez "liste d'arguments trop longue" (l'approche avec les for file in *CDI*.dat;
que vous avez utilisé à l'origine est immunisé contre cela).
Peut-être ajuster votre structure de répertoire (par exemple, seulement *CDI*.dat
dans le répertoire courant et les sous-répertoires, recherche récursive autorisée ou pas de sous-répertoires du tout) et le format du fichier de motifs. L'idée est d'utiliser
grep -lr -f "$TMP/TempBatchData.txt"
ou quelque chose de similaire. Note -r
n'est pas requis par POSIX, dans cet exemple sa signification est celle de GNU grep
: lire tous les fichiers sous le répertoire de travail actuel, de manière récursive.
Un seul grep
devrait être plus rapide que toute solution qui utilise find -exec
o read
(et fait correspondre les chaînes de caractères de n'importe quelle manière).