So suchen Sie nach einer numerisch benannten Datei und kopieren sie, falls vorhanden, unter einem neuen Namen mit der nächsten fortlaufenden Nummer

So suchen Sie nach einer numerisch benannten Datei und kopieren sie, falls vorhanden, unter einem neuen Namen mit der nächsten fortlaufenden Nummer

Zunächst möchte ich mich für meinen Mangel an Wissen entschuldigen; dies ist buchstäblich mein allererstes Bash-Skript und meine Linux-Kenntnisse sind praktisch nicht vorhanden. Erklärende Antworten wären sehr willkommen; ich würde gerne das Warum erfahren, nicht nur das Wie.

Ich versuche, ein Skript zu schreiben, um einen langwierigen Prozess zu automatisieren, der mehrmals täglich durchgeführt werden muss. Kurz gesagt, dieses Skript sollte einen Satz von Dateien basierend auf bestimmten Anforderungen vorbereiten. Das Skript muss entweder eine Vorlagendatei verschieben und ihr eine Versionsnummer zuweisen oder eine vorhandene Datei mit einer neuen Versionsnummer kopieren, basierend darauf, was in einem bestimmten Verzeichnis gefunden wird (z. B. erstellen, wenn leer, kopieren, wenn dort etwas vorhanden ist).

Die Datei könnte beispielsweise heißen

JJJJMMTT_##_Benutzername_testfile.json

wobei die ## (Versionsnummer) 01 für die erste Erstellung sein sollte, dann 02 für die Kopie, 03 für die Kopie danach usw. Ein einzelnes Verzeichnis kann mehr als 10 dieser Dateien enthalten, alle mit unterschiedlichen Daten und fortlaufenden Versionsnummern, sowie andere Dateien, die dasselbe Format verwenden, aber mit einer anderen Endung als testfile.json.

Ich kann anscheinend keine Möglichkeit finden, das Skript im Verzeichnis „Test“ nach der Datei mit der Endung „testfile.json“ suchen zu lassen, die die höchste Versionsnummer hat. Wenn diese gefunden wird, extrahiert sie die Versionsnummer als Variable/Parameter, die ich wieder an die CP-Sequenz übergeben kann.

An diesem Punkt bin ich mir noch nicht einmal sicher, welchen Befehl ich verwenden soll. Das Internet bietet alles von grep über awk bis hin zu Auflisten und Sortieren … mir schwirrt der Kopf!

Für jede Hilfe wäre ich dankbar. Ich habe alle identifizierenden Informationen entfernt. Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Antwort1

Lassen Sie uns es in mehrere Schritte aufteilen.

Wir werden eine Funktion schreiben, die die nächste Zahl zurückgibt. Wir streben eher nach Einfachheit als nach maximaler Effizienz

Sie müssen ihm einen Verzeichnisnamen geben

testfile.jsonSie müssen den Teil des Dateinamens angeben

Wir müssen alle Dateien in diesem Verzeichnis finden, die mit dieser Endung enden.

Parameter werden mit $1, $2 usw. an eine Funktion übergeben.

getnum(){
  ls "$1" | grep "$2\$"
}

Verwenden Sie „cut“, um nur das zweite Feld herauszuziehen, und verwenden Sie es _als Trennzeichen. (Beachten Sie, dass ich in diesem Fall sed anstelle von grep und „cut“ verwenden würde. Andere würden vielleicht awk verwenden, aber wir entscheiden uns hier für die Einfachheit.)

getnum() {
 ls "$1" | grep "$2\$" | cut -d_ -f 2
}

Verwenden Sie „Sort“, um sie numerisch zu sortieren

getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n
}

Verwenden Sie head, um nur den ersten Wert zu erhalten

 getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1
 }

Fassen Sie dies zusammen, damit wir den Wert in einer lokalen Variablen erhalten

getnum() {
      local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
}

Wenn keine Werte vorhanden waren, setzen Sie den alten Wert auf 0. Drucken Sie eine zweistellige Zahl aus, die um eins höher ist als die alte.

 getnum() {
  local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
  if [ "$oldnum" = "" ]
  then
      oldnum=0
  fi
  printf "%02d\n" $(($oldnum+1))
 }

Beachten Sie, dass ich den Test für nicht festgelegte oldnum hätte weglassen können, da in diesem Fall $((oldnum+1))auf erweitert würde $((+1)). Ich kann auch Ausdrücke wie $((${oldnum:-0}+1)) verwenden. Weitere Informationen finden Sie in den Handbüchern.

Sie könnten dann eine Funktion wie diese verwenden

  dir=somewhere/logs
  ext=testfile.json
  cp template "$dir/$(date +%Y%m%d_)$(getnum "$dir" "$ext")_$USER_$ext"

verwandte Informationen