Probleme, verdächtige Fragmente:
$matched_file_id
enthält null oder mehr Werte, der Vergleich ist$FILE_ID
nur dann erfolgreich, wenn es einen Wert gibt;$matched_file_id
wird einmal pro gesetztline
, Vergleich$FILE_ID
wird einmal pro durchgeführtFILE_ID
;- Es gibt ein Extra
done
am Ende (?); column values
sollte zu einem Kommentar gehören;- Variablen werden nicht in Anführungszeichen gesetzt;
TMP
sollte festgelegt werden.
Dies ist ein neu geschriebenes Verfahren. Es ist nicht völlig gleichwertig, aber der Ansatz scheint besser zu sein:
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
Erläuterung:
find
findet alle Dateien, die dem*CDI*.dat
Muster entsprechen.- Für jede solche Datei wird eine Shell ausgeführt, um eine Pipe zu verarbeiten.
cut
extrahiert die dritte Spalte.grep
quietly (-q
) prüft, ob ein literaler String (-F
) aus der angegebenen Datei (-f
) in der Ausgabe voncut
als ganze Zeile (-x
) vorhanden ist.- Wenn ja,
find
wird der Pfad zur Datei gedruckt.
Hinweise, Unterschiede, Macken:
find
wirkt rekursiv. Um nur das aktuelle Verzeichnis ohne Unterverzeichnisse zu verarbeiten, benötigen Sie-maxdepth 1
(nicht für POSIX erforderlich) oder eine POSIX-Lösung aus dieser Frage, oder lassen Sie die Shell expand*CDI*.dat
(find *CDI*.dat -type f -exec …
), die ihre Schattenseiten hat.find
druckt Pfade mit führenden./
. Um Basisnamen zu erhalten, benötigen Sie-printf '%f\n'
(nicht POSIX) anstelle von-print
oder zB-exec basename {} \;
(POSIX-kompatibel) statt-print
.grep -F
passt auf wörtliche Zeichenfolgen. In Ihrem Code wird jede Zeile$TMP/TempBatchData.txt
zweimal zweimal implizit verarbeitet:- mit
read FILE_ID
(im Gegensatz zuread -r FILE_ID
), - innerhalb der
[[ $matched_file_id == $FILE_ID ]]
(Vergleiche mit[[
Perform Pattern Matching mit der nicht zitierten Zeichenfolge auf der rechten Seite, nicht nur ein einfacher Zeichenkettenvergleich).
Ich bin mir nicht sicher, ob Sie sich darauf verlassen. Möglicherweise möchten Sie meinen Code anpassen.- mit
Im Titel wird das Kopieren von Dateien in ein anderes Verzeichnis erwähnt. Bei meinem Ansatz brauchen Sie dafür nicht
final_cdi_list.txt
zu arbeiten. Verwenden Sie einfach-exec cp {} "/another/directory" \;
statt-print
.
Die Suche nach passenden Dateien kann mit der Sohle erledigt werden grep
. Sie müssen jedoch das Muster anpassen. Beispiel:
grep -l '^[0-9]*|[0-9]*|840920|' *CDI*.dat
Sie können viele Muster in einer Datei ( -f "$TMP/TempBatchData.txt"
) haben, aber sie müssen wie oben sein. Wenn zu viele Dateien übereinstimmen, erhalten *CDI*.dat
Sie eine "Argumentliste zu lang" (der Ansatz, den for file in *CDI*.dat;
Sie ursprünglich verwendet haben, ist dagegen immun).
Passen Sie möglicherweise Ihre Verzeichnisstruktur an (z. B. nur *CDI*.dat
Dateien im aktuellen Verzeichnis und in den Unterverzeichnissen, rekursive Suche erlaubt oder überhaupt keine Unterverzeichnisse) und das Musterdateiformat. Die Idee ist zu verwenden
grep -lr -f "$TMP/TempBatchData.txt"
oder etwas ähnliches. Hinweis -r
ist für POSIX nicht erforderlich, in diesem Beispiel ist die Bedeutung von GNU grep
: Lesen Sie alle Dateien rekursiv unter dem aktuellen Arbeitsverzeichnis.
Ein einzelner grep
Prozess sollte schneller sein als jede Lösung, die find -exec
oder read
(und in welcher Weise auch mit Zeichenfolgen übereinstimmt).