it-swarm.com.de

Möchten Sie Textdateien für jedes PNG im Ordner erstellen

Ich habe dieses Skript

#!/bin/bash

folder='/home/data/mnist/training'

for filePng in $folder/*
do
touch $filePng.txt
done

Es funktioniert nur, dass für eine Datei mit dem Namen 001.png001.png.txt anstelle von 001.txt erstellt wird.

Wie kann ich das ändern?

12
Qubix

Sie können den Befehl basename hier verwenden:

touch "$folder/$(basename "$filePng" .png).txt"

Beachten Sie den zusätzlichen $folder/. Dies ist erforderlich, da der Befehl basename den Pfad von entfernt.

16
Wayne_Yux

Sie können die vorhandene Erweiterung mit den Funktionen Parametererweiterung der Shell entfernen

${parameter%pattern} Das 'Muster' wird mit dem Ende von 'Parameter' abgeglichen. Das Ergebnis ist der erweiterte Wert von 'parameter', wobei die kürzeste Übereinstimmung gelöscht wird.

Also ersetze in deinem Fall $filePng.txt durch "${filePng%.png}.txt"

32
steeldriver

Bei Variation dessen, was der Stahltreiber bereits erwähnt hat - Parametererweiterung - können wir String-Ersetzungen verwenden, um die Arbeit zu erledigen. Zusätzlich sollten Sie Variablen zitieren. Unten sehen Sie Ihr bearbeitetes Skript.

#!/bin/bash

folder='/home/data/mnist/training'

for filePng in "$folder"/*
do
    touch "${filePng/.png/.txt}"
done
10

Wenn Sie viele Dateien zur Erstellung haben, lohnt es sich, mehr als eine Datei gleichzeitig zu „berühren“, damit Sie nicht für jede Datei einen neuen Prozess starten müssen (welcher dauert bei mehrtausendfacher Ausführung ziemlich lange).

Option 1: Mustersubstitution + xargs

Diese Option gibt mehrere Pfade gleichzeitig an den Befehl touch weiter, normalerweise einige Tausend oder was auch immer das System auf eine einzelne Befehlszeile passen kann.

find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --

Option 2: Parametererweiterung + Befehlsausgabeumleitung

Diese Option führt touch überhaupt nicht aus, sondern verwendet stattdessen Bash-/Bourne-/POSIX-Shell-Funktionen, für die überhaupt keine Unterprozesse erforderlich sind.

for f in "$folder"/*.png; do
    : >> "${f%.png}.txt"
done
9
David Foerster

Wenn Sie sicher sind, dass Sie keine Dateien mit .png in der Mitte des Namens haben, können Sie einfach ein Array mit Parametererweiterung verwenden:

pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"

Dadurch werden alle Pfade zu den Dateien, die mit .png enden, in einem Array gespeichert. Anschließend wird mithilfe der Parametererweiterung die Liste der .txt -Dateien erstellt, indem .png für .txt angegeben wird einer.

Beachten Sie, dass dies fehlschlägt, wenn Sie über so viele Dateien verfügen, dass nicht alle als Argumente für denselben Aufruf von touch übergeben werden können.

4
Tom Fenech