web-dev-qa-db-fra.com

Vous voulez créer des fichiers texte pour chaque png du dossier

J'ai ce script

#!/bin/bash

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

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

Cela fonctionne, juste que, pour un fichier nommé 001.png, il crée 001.png.txt au lieu de 001.txt.

Comment puis-je modifier cela?

12
Qubix

Vous pouvez utiliser la commande basename ici:

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

Notez le $folder/ supplémentaire. Cela est nécessaire car la commande basename supprime le chemin de.

16
Wayne_Yux

Vous pouvez supprimer l'extension existante à l'aide des fonctionnalités expansion des paramètres du shell.

${parameter%pattern} Le "motif" correspond à la fin du "paramètre". Le résultat est la valeur développée de 'paramètre' avec la correspondance la plus courte supprimée.

Donc, dans votre cas, remplacez $filePng.txt par "${filePng%.png}.txt"

32
steeldriver

Avec une variation de ce que steeldriver a déjà mentionné - l’extension des paramètres - nous pouvons utiliser le remplacement de chaîne pour faire le travail. De plus, vous devriez citer des variables. Vous trouverez ci-dessous votre script modifié.

#!/bin/bash

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

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

Si vous avez beaucoup fichiers à créer, il serait intéressant de "toucher" plus d’un fichier à la fois, de sorte que vous n’ayez pas besoin de créer un nouveau processus pour chacun d’eux (qui prend un certain temps si elle est exécutée plusieurs milliers de fois).

Option 1: substitution de modèle + xargsname__

Cette option fournit plusieurs chemins d'accès à la commande touchà la fois, généralement quelques milliers, ou tout ce que le système peut contenir sur une seule ligne de commande.

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

Option 2: expansion du paramètre + redirection de la sortie de commande

Cette option n'exécute pas du tout touchmais utilise plutôt les fonctionnalités de Bash/Bourne/POSIX Shell qui ne nécessitent aucun sous-processus.

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

Si vous êtes sûr de ne pas avoir de fichiers avec .png quelque part au milieu du nom, vous pouvez simplement utiliser un tableau avec le développement de paramètres:

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

Ceci stocke tous les chemins des fichiers se terminant par .png dans un tableau, puis utilise le développement de paramètres pour créer la liste des fichiers .txt, en substituant .png à .txt sur chacun d'entre eux.

Gardez à l’esprit que cela cassera si vous avez tellement de fichiers qu’ils ne peuvent pas tous être passés en tant qu’arguments au même appel de touch.

4
Tom Fenech