J'essaye de développer la même chose. Mais mon exigence est un peu différente. Je voudrais compter le nombre de délimiteurs dans la 1ère ligne et la 2ème ligne. Si les délimiteurs des deux lignes correspondent, très bien, sinon le fichier doit être déplacé vers le dossier de rejet. Ci-dessous le script. Mais ici, j'ai une question, comment puis-je compter pour 3 délimiteurs différents dans différents fichiers. Par exemple, j'ai des séparateurs virgule, point-virgule et tube. Dans le script ci-dessous dans la commande sed, comment vérifier 3 types de délimiteurs en même temps?
pathname=/opt/interfaces/sample_check/mvfiles/inbox findresult=$(find $pathname -type f ( -name "messagemulti.csv" -or -name "messagesemi.txt" -or -name "comma2.txt" -or -name "messagepipe.txt" -or -name "tokkalodi.txt" -or -name "ADMC_POSITION-LT3213.csv" -or -name "DMC_CASHFLOW248.csv" -or -name "ADMC_EQBASKET-WEIGHTS_52387.csv" -or -name "ADMC_POSITION-DDD7.csv" -or -name "ADMC_POSITION-DDD7.csv" )) Count=sed -n 1p $findresult | tr ',' '\n' | wc -l Count2=sed -n 2p $findresult | tr ',' '\n' | wc -l echo $Count echo $Count2 if [ $Count != $Count2 ] then echo "Mis Match" mv $findresult /opt/interfaces/sample_check/mvfiles/reject else echo "Match" exit fi
5 Réponses :
Je viens de créer un fichier, contenant uniquement des virgules, des points-virgules et des caractères pipe:
echo $(($(grep -o "," test.txt | wc -l) + $(grep -o ";" test.txt | wc -l) + $(grep -o "|" test.txt | wc -l)))
Ensuite, j'ai exécuté la commande suivante:
echo ",,,;;;;|||||" >test.txt
Cela compte les délimiteurs dans tout le fichier, pas seulement les deux premières lignes
chat test.txt | tête -2 | grep -o "," | wc -l
, donc vous ne comptez que les deux premières lignes.
OP veut comparer le décompte de la première ligne avec le décompte de la seconde.
Si aucun des délimiteurs ne fait autrement partie des deux premières lignes, vous pouvez utiliser ce script générique de GNU awk:
parse.awk
awk -f parse.awk infile1 infile2 ...
Salut Thor, merci. Pourriez-vous s'il vous plaît expliquer votre code. Je ne comprends pas ce que fait le prochain fichier.
@KiranChapidi: Voir les commentaires en ligne
J'ai plusieurs fichiers d'environ 50 fichiers, arrive au hasard dans le système. Les fichiers peuvent contenir l'un des trois délimiteurs (virgule, point-virgule ou tube). si la 1ère ligne à l'intérieur du nombre de délimiteurs de fichier ne correspond pas au nombre de délimiteurs de la 2ème ligne, le fichier doit être déplacé vers le dossier de rejet.
@KiranChapidi: Intégrez le script dans votre processus, par exemple: find ... -exec awk -f parse.awk {} + | xargs mv -t / chemin / vers / rejeter
. Notez que vous devez supprimer le bit "Mismatch:"
de l'instruction d'impression
J'ai trouvé quelque chose ci-dessous pour inclure tous les délimiteurs en même temps. Veuillez vérifier si cela est correct.
pathname=/opt/interfaces/sample_check/mvfiles/inbox findresult=$(find $pathname -type f ( -name "messagemulti.csv" -or -name "messagesemi.txt" -or -name "comma2.txt" -or -name "messagepipe.txt" -or -name "tokkalodi.txt" -or -name "ADMC_POSITION-LT3213.csv" -or -name "DMC_CASHFLOW248.csv" -or -name "ADMC_EQBASKET-WEIGHTS_52387.csv" -or -name "ADMC_POSITION-DDD7.csv" -or -name "ADMC_POSITION-DDD7.csv" )) Count=sed -n 1p $findresult | tr '[,;|]' '\n' | wc -l Count2=sed -n 2p $findresult | tr '[,;|]' '\n' | wc -l echo $Count echo $Count2 if [ $Count != $Count2 ] then echo "Mis Match" mv $findresult /opt/interfaces/sample_check/mvfiles/reject else echo "Match" exit fi
Vous pouvez compter les délimiteurs en les déplaçant sur une nouvelle ligne, en les remplaçant par ';', et en les comptant:
if [[ $(sed '1s/[^|,;]//g;s/././g' ${findresult}) != $(sed '2s/[^|,;]//g;s/././g' ${findresult}) ]]; then
Lorsque vous voulez seulement savoir lesquels ont le même nombre, vous pas besoin de les compter.
Supprimez tous les autres caractères et remplacez tout caractère restant par un point.
sed '2 s/[|,;]/\n;/g' ${findresult} | grep -c ';'
sur le type de shell bash
i= pathname=/opt/interfaces/sample_check/mvfiles/inbox for file in messagemulti.csv messagesemi.txt comma2.txt messagepipe.txt tokkalodi.txt ADMC_POSITION-LT3213.csv DMC_CASHFLOW248.csv ADMC_EQBASKET-WEIGHTS_52387.csv ADMC_POSITION-DDD7.csv ADMC_POSITION-DDD7.csv { while read -r l ;do s=${l//[!,;\|]}; c=${#s}; ((++i==1))&&d=$c; if((i==2));then ((d==c)) ||mv -v $file $pathname/$file ;fi ;done<$file }
J'ai essayé de reformater votre code pour qu'il ressemble à du code. Veuillez vérifier que je n'ai pas modifié le sens.
Merci Dave, je suis nouveau sur le stackoverflow
Aucun problème. Si vous prévoyez de traîner, cela vaudra la peine de vous apprendre comment Markdown fonctionne.
Tout à l'heure, j'ai appris à le faire en donnant 4 fois l'espace :) Merci Dave