12 votes

Voulez-vous créer des fichiers txt pour chaque png dans le dossier

J'ai ce script

#!/bin/bash

dossier='/home/data/mnist/training'

pour fichierPng dans $dossier/*
faire
touch $fichierPng.txt
fin

Ça fonctionne, mais pour un fichier nommé 001.png, il crée 001.png.txt au lieu de 001.txt.

Comment puis-je modifier cela?

31voto

steeldriver Points 118154

Vous pouvez supprimer l'extension existante en utilisant les fonctionnalités d' extension de paramètre du shell

${parameter%pattern} Le 'pattern' est comparé à la fin de 'parameter'. Le résultat est la valeur étendue de 'parameter' avec la suppression du match le plus court.

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

16voto

Wayne_Yux Points 4743

Vous pouvez utiliser la commande basename ici:

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

Notez l'ajout de $folder/. C'est nécessaire car la commande basename supprime le chemin de.

10voto

Sergiy Kolodyazhnyy Points 97292

Avec une variation de ce que steeldriver a déjà mentionné - l'expansion de paramètres - nous pouvons utiliser le remplacement de chaînes pour effectuer la tâche. De plus, vous devriez citer les variables. Ci-dessous se trouve votre script modifié.

#!/bin/bash

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

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

9voto

David Foerster Points 34353

Si vous avez beaucoup de fichiers à créer, il serait utile de "toucher" plusieurs fichiers en même temps, afin de ne pas nécessiter la création d'un nouveau processus pour chacun d'entre eux (ce qui prendrait beaucoup de temps s'ils étaient exécutés plusieurs milliers de fois).

Option 1: substitution de motif + xargs

Cette option fournira plusieurs chemins vers la commande touch en une seule fois, généralement quelques milliers ou ce que le système peut contenir sur une seule ligne de commande.

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

Option 2: expansion de paramètres + redirection de sortie de commande

Cette option n'exécute pas du tout la commande touch mais utilise plutôt les fonctionnalités de shell Bash/Bourne/POSIX qui ne nécessitent pas du tout de sous-processus.

for f in "$dossier"/*.png; do
    : >> "${f%.png}.txt"
done

4voto

Tom Fenech Points 140

Si vous êtes sûr que vous n'avez pas de fichiers avec .png quelque part au milieu du nom, alors vous pouvez simplement utiliser un tableau avec expansion de paramètres :

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

Cela stocke tous les chemins des fichiers se terminant par .png dans un tableau, puis utilise l'expansion de paramètres pour créer la liste des fichiers .txt, en remplaçant .png par .txt sur chacun.

Gardez à l'esprit que cela ne fonctionnera pas si vous avez tellement de fichiers qu'ils ne peuvent pas tous être passés comme arguments à la même invocation de touch.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X