web-dev-qa-db-fra.com

Écrire une valeur incrémentielle dans tous les fichiers correspondant à un nom de fichier dans des sous-répertoires

J'essaie d'effectuer un certain nombre de tests sur un algorithme et, en tant que tel, un certain nombre de répertoires contenant exactement les mêmes données (sous-répertoires et fichiers) à exécuter sur un cluster. Je voudrais que tous ces répertoires contiennent un fichier appelé randomseed.txt qui contient un entier unique. Actuellement, les fichiers randomseed existent, mais contiennent le même entier: 1. Existe-t-il un script bash que je pourrais utiliser ou une variante de find que je pourrais utiliser pour y parvenir simplement?

Mon idée était quelque chose comme ça:

#!/bin/bash

declare -i VAR
VAR=1

find . -type f -name "randomseed.txt" -execdir VAR=$VAR+1 | $VAR > randomseed.txt \;

echo $VAR
echo done

mais je ne sais pas trop comment ou si je peux faire quelque chose comme ceci avec -exec ou -execdir.

3
onyinyang

Cela devrait fonctionner pour vous:

/bin/bash
x=1
find . -name 'randomseed.txt' | \
while IFS= read file ; do
  echo $x > "$file"
  x=$(($x+1))
done

IFS= est d'empêcher la rupture d'espaces dans le chemin du fichier s'ils existent, cela n'arrivera probablement pas dans votre cas.

La tuyauterie résulte de la recherche dans la boucle while read qui attribue la valeur à file exécute ensuite le corps de la boucle. x=$(($x+1)) est votre brut x+=1

4
Maeve Kennedy

Au lieu d'utiliser find, vous pouvez activer globstar pour rendre le globging Shell récursif.

 shopt -s globstar

cd dans le répertoire parent de cette structure, puis pour tester (écraser) l'écriture des fichiers:

n=0; for i in **; do [[ -d "$i" ]] && echo "echo $((++n)) >" "$i"/randomseed.txt; done

Vous pouvez voir qu'il va écrire un fichier dans chaque répertoire à chaque niveau. Vous pouvez ensuite supprimer l'écho supplémentaire pour écrire les fichiers:

n=0; for i in **; do [[ -d "$i" ]] && echo $((++n)) > "$i"/randomseed.txt; done

Vous voudrez peut-être annuler la définition de globstar lorsque vous aurez terminé:

shopt -u globstar
3
Zanna

Exécutez une boucle créant des nombres et demandez à la commande exécutée find- de lire ces nombres:

for ((i = 1; ; i++)); do echo $i; done | 
  find . -type f -name "randomseed.txt" -exec sh -c 'read i; echo $i > "$1"' _ {} \;

Vous pouvez également utiliser seq:

seq 1 inf | find . -type f -name "randomseed.txt" -exec sh -c 'read i; echo $i > "$1"' _ {} \;
3
muru