2009-10-27 7 views
0

Pour traiter un tas de données et le préparer à être inséré dans notre base de données, nous générons un tas de scripts shell. Chacun d'eux a environ 15 lignes, une pour chaque table que les données vont. Un lot d'importation récent, certains des fichiers d'importation ont échoué dans une table particulière. Donc, j'ai un tas de scripts shell (environ 600) où je dois commenter les 7 premières lignes, puis relancer le fichier. Il y a environ 6000 scripts shell dans ce dossier, et rien sur un fichier particulier ne peut me dire s'il a besoin de l'éditer. J'ai une liste des fichiers que j'ai tirés de la sortie de la base de données.Script Bash pour éditer un tas de fichiers

Alors, comment écrire un script bash (ou quoi que ce soit d'autre qui fonctionnerait mieux) pour prendre cette liste de noms de fichiers et pour chacun d'eux, commenter les 7 premières lignes, et exécuter le script?

EDIT:

#!/usr/bin/env sh 

cmd1 
cmd2 
cmd3 
cmd4 
cmd5 
cmd6 
cmd7 
cmd8 

Je ne sais pas comment lisible est. Fondamentalement, les 7 premières lignes (sans compter la première ligne) doivent avoir un # ajouté au début d'eux. Note: les fichiers ont été édités pour raccourcir chaque ligne et couper partiellement la copie de VIM. Mais dans la partie principale de chaque fichier, il y a une ligne commençant par echo, puis une ligne commençant par sqlldr

+0

Fournissez des exemples de fichiers d'entrée et décrivez clairement comment vous souhaitez que la sortie, le cas échéant, soit similaire à ... – ghostdog74

+0

Édité pour inclure un fichier d'exemple. –

+0

Pour la postérité: vous devez faire chmod + x line.new ainsi –

Répondre

4

En utilisant sed, vous pouvez spécifier une plage de numéros de ligne dans le fichier à modifier.

#!/bin/bash 

while read line 
do 
    # add a comment to beginning of lines 1 - 7 and rename the script 
    sed '3,9 s/^/#/' $line > $line.new 
    exec $line.new 
done < "filelist.txt" 

Vous pouvez tester cela avant de l'exécuter sur tous ces scripts ...

EDIT: changé les numéros de lignes pour tenir compte des commentaires.

+0

? S: 1)^est le caractère spécial pour le début de la ligne? 2) Est-ce que 1 est la première ligne, ou 0 la première ligne d'un fichier? 3) Comment cela peut-il être configuré pour prendre en entrée la liste des fichiers à changer? IE comment puis-je dire à la ligne de lecture pendant tirer de la liste de fichiers?Est-ce aussi simple que de mettre la liste des fichiers dans un fichier et de rediriger les entrées de ce fichier? –

+1

^est le caractère qui représente le début d'une ligne. 1 est la première ligne. Cela va lire un fichier "filelist.txt" ligne par ligne et changer chaque fichier dans cette liste. Cela ne changera que les lignes 1-7 comme demandé - y compris la première ligne. Les nombres au début peuvent être ajustés pour adapter à ce que vous recherchez. – Buggabill

+0

Êtes-vous en train d'ouvrir "filelist.tx" ou est-il en train d'être redirigé ou redirigé vers le script? –

1

En fin de compte, vous allez vouloir utiliser la commande linux sed. Quelle que soit la logique que vous devez placer dans le script, vous savez. Mais votre script appellera finalement sed. http://lowfatlinux.com/linux-sed.html

3

En gros:

#!/bin/sh 
for file in "[email protected]" 
do 
    out=/tmp/$file.$$ 
    sed '2,8s/^/#/' < $file > $out 
    $SHELL $out 
    rm -f $out 
done 

En supposant que vous ne se soucient pas de la vérification des conditions de course, etc.

+0

Ce qui pourrait causer des conditions de course dans cette situation? Cela ne se produirait-il que si plusieurs instances de ce script s'exécutaient en même temps? –

+0

Plusieurs instances de script _this_ devraient être correctes (c'est ce que le $$ est pour, il ajoute l'id de processus aux fichiers). Le problème est un utilisateur malveillant qui crée un tas de readonly /tmp/foo.[une gamme de devinettes à vos fichiers pid] avec des choses qu'ils veulent exécuter en utilisant vos privilèges. –

+0

Ah, d'accord. Merci pour le conseil –

1

ex semble fait pour ce que vous voulez faire.

Par exemple, pour l'édition d'un fichier, un document en:

#!/bin/sh 

ex test.txt << END 
1,12s/^/#/ 
wq 
END 

Ce commenterons les 12 premières lignes dans "test.txt". Pour votre exemple, vous pouvez essayer "$FILE" ou similaire (y compris les citations!).

les exécuter ensuite de la manière habituelle, à savoir ./"$FILE"

modifier: $SHELL "$FILE" est probablement une meilleure approche pour les exécuter (d'un des commentateurs ci-dessus).

Questions connexes