Ho questa sceneggiatura
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Funziona, solo che, per un file chiamato 001.png, crea 001.png.txtinvece di 001.txt.
Come posso modificarlo?
Ho questa sceneggiatura
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Funziona, solo che, per un file chiamato 001.png, crea 001.png.txtinvece di 001.txt.
Come posso modificarlo?
Risposte:
Puoi usare il basenamecomando qui:
touch "$folder/$(basename "$filePng" .png).txt"
Nota l'ulteriore $folder/. Questo è necessario poiché il comando basename rimuove il percorso da.
$filePng: erano anche utili.
$( )stabilisce un nuovo contesto di quotazione.
È possibile rimuovere l'estensione esistente utilizzando le funzionalità di espansione dei parametri della shell
${parameter%pattern}Il "modello" è abbinato alla fine del "parametro". Il risultato è il valore espanso di "parametro" con la corrispondenza più breve eliminata.
Quindi, nel tuo caso, sostituiscilo $filePng.txtcon"${filePng%.png}.txt"
Con la variazione di quanto già detto steeldriver - espansione dei parametri - possiamo usare la sostituzione di stringhe per fare il lavoro. Inoltre, dovresti citare le variabili. Di seguito è riportato il tuo script modificato.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
Se hai molti file da creare, varrebbe la pena "toccare" più di un file alla volta, quindi non è necessario eseguire il fork di un nuovo processo per ciascuno di essi (che richiede parecchio tempo se eseguito in più mille volte).
xargsQuesta opzione fornirà più percorsi al touchcomando contemporaneamente, di solito qualche migliaio o qualunque cosa il sistema possa adattare su una singola riga di comando.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
Questa opzione non funziona touchaffatto ma utilizza invece le funzionalità della shell Bash / Bourne / POSIX che non richiedono affatto processi secondari.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done
Se sei sicuro di non avere file con .pngqualcosa nel mezzo del nome, puoi semplicemente usare un array con espansione dei parametri:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
Questo memorizza tutti i percorsi dei file che finiscono in .pngun array e quindi utilizza l'espansione dei parametri per creare l'elenco di .txtfile, sostituendo .pngper .txtognuno.
Tieni presente che questo si interromperà se hai così tanti file che non possono essere passati tutti come argomenti alla stessa invocazione di touch.
for filePng in "$folder"/*etouch "$filePng".txt- nota che li citi solo quando preceduto da a$.