Ich habe die Skripte basierend auf den in Ihrem Kommentar angegebenen Dateinamenbeispielen aktualisiert:
"Liam sur la moto (VHS) (2001) - Maison 13100.m2ts"
"M&L Plage 1080i (2012) - Camargue 30240.m2ts
Ich habe mir zwei Methoden ausgedacht, um diese Namenskonvention zu handhaben.
Die erste ist anzunehmen, dass das Jahr in jedem Fall in Klammern steht. Ich habe das 'erste' Skript aktualisiert, um diesen Fall widerzuspiegeln. Es ist einfach eine Aktualisierung des verwendeten Regex-Musters.
regexPat='\(\K[0-9]{4,4}(?=\))'
Das zweite Skript wurde aktualisiert, um eine andere Methode zu zeigen, bei der wir nicht sicher sein können, ob das Jahr in Klammern steht. Hier lesen wir das Ergebnis der grep-Auswertung als Array aus, falls es mehrere Übereinstimmungen gibt, und führen dann eine Überprüfung des Jahres durch - dh das Jahr muss zwischen 1970 und 2020 liegen; Ansonsten nehmen wir an, dass es kein Jahr ist.
Beachten Sie, dass der readarrayBefehl (auch Mapfile genannt) nur in Bash-Versionen 4.x + verfügbar ist. Am unteren Rand ist eine tragbare Version mit nur read. Es kann schwierig sein , die Ausgabe zu analysieren, findohne dass aufgrund von Leerzeichen oder Sonderzeichen in den Dateinamen Fehler auftreten.
Skript 1
#!/bin/bash
# Create test files
touch abcd\({2001,1985,1984,1931}\)efgh.m2ts
touch abcd{24001,198a5,19b84,1912331,1293}.m2ts
touch "abcd 1232 adffd.m2ts"
touch "Liam sur la moto (VHS) (2001) - Maison 13100.m2ts"
touch "M&L Plage 1080i (2012) - Camargue 30240.m2ts"
TestScriptResultFile="./CamCorderFindResult.file"
touch $TestScriptResultFile
regexPat='\(\K[0-9]{4,4}(?=\))'
readarray fileList <<<"$(IFS="\n" ; find . -name "*.m2ts" -exec basename {} \;)"
for i in "${fileList[@]}"; do
echo "Processing File: $i"
if year=$(grep -oP "$regexPat" <<<"$i"); then
if [ "$year" -le 1984 ]; then
echo "1984 or earlier: $i" >> "$TestScriptResultFile"
else
echo "After 1984: $i" >> "$TestScriptResultFile"
fi
else
echo "No valid year found in file $i"
fi
done
1. Verwenden Sie den findBefehl, um eine Dateiliste abzurufen und mit ein Array zu speichern readarray.
- Setzen Sie den Feldtrenner auf eine neue Zeile:
IFS=$'\n'
- Verwenden Sie ein
-execArgument, finddas basenamefür jede Datei ausgeführt wird, um nur den Dateinamen und nicht den Pfad abzurufen.
- Das
findAusgangssignal wird in ein Array gerichtet durch die Verwendung Befehls Substitution und A ‚ Hier String‘ , <<<und den readarrayBefehl
2. Durchlaufen Sie das Array mit den Dateinamen
3. Verwenden Sie grep und regexPat, um das eingebettete Jahr zu finden
Das Regex-Muster, das ich verwendet habe, stimmt mit 6 Zeichen in einer Zeichenfolge überein, wenn das erste Zeichen ein a ist (, gefolgt von genau 4 Zahlen [0-9]{4,4}und abgeschlossen durch ein a )am Ende.
Um nur die 4 Zahlen dazwischen (hoffentlich das Jahr) auszugeben, wird das Argument -Pgegeben, nach 'Perl Regex' zu suchen, wodurch unter anderem übereinstimmende Zeichen von erfassten (Ausgabe-) Zeichen getrennt werden können.
- Das
/Kwird dazu führen, dass grep nichts ausgibt, was vor dem /Kin dem Muster übereinstimmt (auch bekannt als Look-Ahead ).
Schließlich wird das Schließen )aus der Ausgabe entfernt, indem ein Look-Behind-Non-Capture verwendet wird, das dem ähnelt /K. Sie können für beide dieselbe Syntax verwenden. Das untere Skript zeigt die Look-Ahead-Methode, die nicht verwendet wird /K.
Das -oFlag weist grep an, nur den erfassten, übereinstimmenden Teil der Zeichenfolge auszugeben, in unserem Fall eine 4-stellige Zahl.
Der Rest des Skripts prüft die Nummer gegen 1984 und protokolliert sie entsprechend.
Hier ist ein weiterer kompakterer Ansatz.
2 Dinge, die hier zu beachten sind
findwird das Argument gegeben, -print0das die Ausgabe beendet.
- Der
readBefehl erhält das Argument -d '', das angibt, dass seine Eingabe mit Null beendet ist. Eine Nullzeichenfolge wird normalerweise \0im Klartext geschrieben . in Bash können Sie ''oder verwenden$'\0'
Skript 2
#!/bin/bash
TestScriptResultFile="./CamCorderFindResult.file"
touch $TestScriptResultFile
regexPat='(?<=[^0-9])[0-9]{4,4}(?=[^0-9])'
find . -name "*.m2ts" -print0 | while IFS= read -r -d '' k; do
i="$(basename "$k")"
echo "Processing File: $i"
if year=($(grep -oP "$regexPat" <<<"$i")); then
for yr in "${year[@]}"; do
if [ "$yr" -lt 1970 ] || [ "$yr" -gt 2020 ]; then
echo " x Out of range year ($yr) parsed from $i"
else
echo " o Found year $yr"
if [ "$yr" -le 1984 ]; then
echo "1984 or earlier: $i" >> "$TestScriptResultFile"
else
echo "After 1984: $i" >> "$TestScriptResultFile"
fi
fi
done
else
echo " x No valid year found in file $i"
fi
done