2017-06-28 6 views
0

J'ai les répertoires ci-dessous dans un fichier d'entrée et j'ai besoin de les créer en boucle.Création de répertoires à partir d'un fichier d'entrée

données/app_rt_ws/Demande/2017_06_27
données/app_rt_ws/Response/2017_06_19
données/app_rt_ws/RTWS
données/app_rt_ws/SDP
données/edge/réponse/20.09.2016
données/edge/response/9-22-2016

Le problème est que je n'ai pas besoin des répertoires au format yyyy_mm_dd ou dd-mm-yyyy qui sont créés lors de l'exécution sur le serveur. J'ai besoin qu'ils soient jetés et que le reste du chemin statique des répertoires soit créé.

J'utilise le code mentionné ci-dessous, mais ne peut pas à comprendre comment omettre mentionnées ci-dessus une partie

for i in `cat /tmp/inputfile.txt` 
do 
echo $i 
cd /opt/app/app 
awk '/date_year/{print $1}' (need to filter out the entries with date) 
mkdir -p $i (need to create rest of the directories) 
done 
+0

Le format de la date dans votre fichier d'entrée n'est pas cohérent. Est-ce possible de distinguer l'année seulement en utilisant 201X? et jj-mm-aaaa devrait être mm-jj-aaaa dans votre cas. droite? – CWLiu

+0

Et est-il exact qu'il y a des lignes sans et avec date mais que vous voulez créer des répertoires à partir des deux? – JFS31

+0

@CWLiu le format de la date n'est pas cohérent. c'est comme ça sur la production. J'ai essayé d'utiliser 'cat /tmp/inputfile.txt | grep -v [0-9] $ 'pour filtrer les entrées où la date a été mentionnée. –

Répondre

0

Vous pouvez utiliser les substitutions de chaîne bash pour se débarrasser de la date.

for i in `cat /tmp/inputfile.txt` 
do 
echo $i 
cd /opt/app/app 
if [[ $i =~ [0-9] ]]; then 
mkdir -p ${i%/*} 
else 
mkdir -p $i 
fi 
done 

La substitution coupe tout après la dernière/donc la date est passée.

Toutefois, si vous voulez juste tous ceux sans chiffres, alors vous pourriez faire:

for i in `cat /tmp/inputfile.txt` 
do 
echo $i 
cd /opt/app/app 
if [[ $i =~ [0-9] ]]; then 
: 
else 
mkdir -p $i 
fi 
done 

sortie de la deuxième version:

data/app_rt_ws/RTWS 
data/app_rt_ws/SDP 

J'espère que c'est ce que vous cherché :)

+0

s'il y a des chiffres dans le fichier mais pas le format de date, votre script l'identifiera mal. – CWLiu

+0

C'est vrai. Mais en ce qui concerne la contribution que j'ai reçue, cela fonctionne. – JFS31

+0

Mais si j'ai une bonne idée pour le rendre plus robuste, je le ferai :) – JFS31

0

Vous pouvez modifier votre script comme suit,

for i in `awk '$0 !~ (/[0-9]{1,2}-[0-9]{1,2}-20[0-9]{2}/ && /20[0-9]{2}_[0-9]{1,2}_[0-9]{1,2}/){print}' inputfile.txt`; 
do 
    echo $i 
    cd /opt/app/app 
    mkdir -p $i 
done 

Et la sortie de la commande awk est comme ça,

$ awk '$0 !~ (/[0-9]{1,2}-[0-9]{1,2}-20[0-9]{2}/ && /20[0-9]{2}_[0-9]{1,2}_[0-9]{1,2}/){print}' inputfile.txt 
data/app_rt_ws/RTWS 
data/app_rt_ws/SDP 
+0

Principes fondamentaux du shell: 1) N'utilisez jamais de backticks obsolètes pour exécuter une commande, utilisez '$ (command)' à la place. 2) N'utilisez jamais 'for i dans $ (commande)' pour mettre en boucle les noms de fichiers, utilisez 'while IFS = read -r i' à la place. 3) Ne jamais laisser les variables de shell non étiquetées 'echo $ i', toujours les citer au lieu de' echo "$ i" '. Ce sont des règles de programmation shell absolument fondamentales, voir toute intro de programmation shell pour plus de détails. –

+1

Merci pour ces conseils, je garderai ces précieuses informations à l'esprit. – CWLiu

0

Avec bash pour expressions rationnelles:

$ cat tst.sh 
while IFS= read -r path; do 
    if [[ $path =~ /([0-9]{4}(_[0-9]{2}){2}|([0-9]{1,2}-){2}[0-9]{4})$ ]]; then 
     path="${path%/*}" 
    fi 
    echo mkdir -p "$path" 
done < "$1" 

$ ./tst.sh file 
mkdir -p data/app_rt_ws/Request 
mkdir -p data/app_rt_ws/Response 
mkdir -p data/app_rt_ws/RTWS 
mkdir -p data/app_rt_ws/SDP 
mkdir -p data/edge/response 
mkdir -p data/edge/response 

Retirez le echo une fois que vous avez testé et sont heureux du résultat. Vérifiez la regexp - vous avez dit que vous vouliez correspondre à dd-mm-yyyy mais votre entrée contenait des dates comme d-mm-yyyy donc idk ce que vous vouliez vraiment et donc je devinais que vous seriez heureux avec 1 ou 2 chiffres, d'où [0-9]{1,2}. Avec d'autres shells, utilisez une déclaration de cas ou similaire pour faire correspondre la date à la fin de la ligne comme un motif de globbing. Vous n'avez PAS besoin d'appeler un outil externe pour effectuer cette vérification.

USING:

for i in `some command` 

est toujours à éviter car il se casse lorsque la sortie some command contient des espaces et il utilise des accents graves dépréciés au lieu de la notation moderne $(some command) et faire:

echo $i 

est toujours à éviter car vous devez toujours citer vos variables shell (echo "$i") sauf si vous avez une raison spécifique de ne pas éviter la division accidentelle de mots et la génération de noms de fichiers.