Προς το περιεχόμενο

Bash script με καταμέτρηση χαρακτήρων


christian-ago

Προτεινόμενες αναρτήσεις

Δημοσ.

Χαιρετώ. Εχω φτιάξει ενα σκριπτακι για να καταμετρω ποσες φορες εμφανιζεται ενας χαρακτήρας μέσα σε ένα οποιοδηποτε αρχείο κειμένου που δίνει ο χρήστης ως όρισμα.

Το προβλημα μου ειναι το εξης. Εχω καταφερει να μετραω ολους τους χαρακτηρες ASCII που βρισκονται στο αρχειο κειμενου,

ενω αυτο που θελω ειναι να μετραει μονο τους λατινικους χαρακτηρες, χωρίς δηλαδη τα κενα, /, $ κλπ.

Υποψιαζομαι οτι γινεται με την tr αλλα πώς.

Επισης θα ηταν πιο ωραιο να εμφανιζα σε ποσοστο επι τοις εκατο την εμφανιση καθε χαρακτηρα. Πως μπορω να παρω το μηκος του πινακα μεσα στο μπλοκ που δουλευω κι ετσι να εφαρμοσω τον τυπο;

Δωστε μου τα φωτα σας.

 

>
echo -e "Give a file to check: \c "

read tx # εδώ αποθηκευεται το ονομα του αρχειου

awk '{ for ( i=1; i<=length; i++ ) arr[substr($0, i, 1)]++ }
{ for ( i in arr ) { print i, arr[i] } }' $tx

Δημοσ.
Χαιρετώ. Εχω φτιάξει ενα σκριπτακι για να καταμετρω ποσες φορες εμφανιζεται ενας χαρακτήρας μέσα σε ένα οποιοδηποτε αρχείο κειμένου που δίνει ο χρήστης ως όρισμα.

Το προβλημα μου ειναι το εξης. Εχω καταφερει να μετραω ολους τους χαρακτηρες ASCII που βρισκονται στο αρχειο κειμενου,

ενω αυτο που θελω ειναι να μετραει μονο τους λατινικους χαρακτηρες, χωρίς δηλαδη τα κενα, /, $ κλπ.

 

Σου κάνει κάτι σαν το παρακάτω ?

>
#!/bin/bash
MYFILE=$1

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
               (( ARR[NUM]++ ))
       done
done < $MYFILE

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
# χαρακτήρες οι οποίοι είναι 65-90 'A-Z' και 97-122 'a-z'
for i in $(seq 65 90) $(seq 97 122); do
       if [[ ${ARR[$i]} != "" ]]; then
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d\n" ${ARR[$i]}
       fi
done

exit 0

Δημοσ.

μπορείς με την tr κάπως έτσι:

 

>tr -d 'A-Z'

αυτό σβήνει όλα τα γράμματα. μπορείς να γράψεις το ίδιο για τα κενά και τα σημεία στίξης ή ό,τι άλλο χρειάζεται να κόψεις.

Μπορείς να χρησιμοποιήσεις και σωλήνωση ( | ) για να γράψεις πολλές εντολές σε μια γραμμή.

Δημοσ.
μπορείς με την tr κπαώς έτσι:

 

>tr -d 'A-Z'

αυτό σβήνει όλα τα γράμματα. μπορείς να γράψεις το ίδιο για τα κενά και τα σημεία στίξης ή ό,τι άλλο χρειάζεται να κόψεις.

Μπορείς να χρησιμοποιήσεις και σωλήνωση ( | ) για να γράψεις πολλές εντολές σε μια γραμμή.

 

Μπορεί να γίνει και απευθείας με μία μόνο tr

>
tr -d -c 'A-Za-z'

Η -d σβήνει όπως είπες και η -c αντιστρέφει την επιλογή. Οπότε η παραπάνω

θα σβήσει τα πάντα εκτός από τα A-Z και a-z, δηλαδή αυτό που θέλει ο OP

Δημοσ.

Ευχαριστω για το script ημιθεε. Παρακατω ειναι ο κωδικας. Προσθεσα μια εντολη που μετραει το συνολο των χαρακτηρων στο αρχειο κειμενου. Πως θα καταφερω να εμφανισω το ποσοστο του καθε χαρακτηρα; Μαλλον με calculator bc αλλα πως γινεται;

 

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
               (( ARR[NUM]++ ))
       done
done < $MYFILE

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
# χαρακτήρες οι οποίοι είναι 65-90 'A-Z' και 97-122 'a-z'
[b]
echo "total = `wc -m $MYFILE | tr -d $MYFILE`"[/b]

for i in $(seq 65 90) $(seq 97 122); do
       if [[ ${ARR[$i]} != "" ]]; then
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d\n" ${ARR[$i]}
       fi
done

exit 0

Δημοσ.

Ευχαριστω για το script ημιθεε. Παρακατω ειναι ο κωδικας. Προσθεσα μια εντολη που μετραει το συνολο των χαρακτηρων στο αρχειο κειμενου. Πως θα καταφερω να εμφανισω το ποσοστο του καθε χαρακτηρα; Μαλλον με calculator bc αλλα πως γινεται;

 

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
               (( ARR[NUM]++ ))
       done
done < $MYFILE

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
# χαρακτήρες οι οποίοι είναι 65-90 'A-Z' και 97-122 'a-z'
[b]
echo "total = `wc -m $MYFILE | tr -d $MYFILE`"[/b]

for i in $(seq 65 90) $(seq 97 122); do
       if [[ ${ARR[$i]} != "" ]]; then
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d\n" ${ARR[$i]}
       fi
done

exit 0

Δημοσ.
Προσθεσα μια εντολη που μετραει το συνολο των χαρακτηρων στο αρχειο κειμενου.

>
[b]
echo "total = `wc -m $MYFILE | tr -d $MYFILE`"[/b]

 

Το παραπάνω μπορεί επίσης να γίνει και με άλλους τρόπους όπως

>
total = $(wc -m $MYFILE | cut -d " " -f1)

 

Στην προκειμένη περίπτωση όμως δεν χρειάζεται να καταφύγουμε σε

εξωτερικές εντολές μια και ήδη μετράμε το μέγεθος κάθε γραμμής, οπότε

θέλουμε απλά μια μεταβλητή που να προσθέτουμε τα επί μέρους μεγέθη.

 

Όσον αφορά το ποσοστό κάθε γράμματος, εφόσον έχουμε το συνολικό μέγεθος

και τον αριθμό εμφανίσεων του κάθε γράμματος, είναι απλά μια διαίρεση.

 

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
[b]let TOTAL=0[/b]

# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
[b]        let TOTAL+=LEN[/b]
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
               (( ARR[NUM]++ ))
       done
done < $MYFILE

[b]# Ο αριθμός θα είναι μικρότερος από αυτόν που εμφανίζει η wc -m γιατί[/b]
[b]# εμείς δεν μετράμε το κάθε newline[/b]
[b]echo Sunolikos arithmos xarakthrwn = $TOTAL[/b]

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
# χαρακτήρες οι οποίοι είναι 65-90 'A-Z' και 97-122 'a-z'

for i in $(seq 65 90) $(seq 97 122); do
       if [[ ${ARR[$i]} != "" ]]; then
[b]                PCT=${ARR[$i]}[/b]
[b]                let PCT*=100[/b]
[b]                let PCT/=TOTAL[/b]
[b]# Το bash δεν υποστηρίζει πραγματικούς αριθμούς οπότε το 0.60% θα γίνει 0%[/b]
[b]# έτσι προσθέτουμε 1 στο κάθε ποσοστό[/b]
[b]                let PCT++[/b]
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d [b]%d%%[/b]\n" ${ARR[$i]}[b] $PCT[/b]
       fi
done

exit 0

 

Επειδή τα ποσοστά είναι μικρά, η παρακάτω έκδοση δεν κοιτά case και

προσθέτει τις εμφανίσεις πεζών-κεφαλαίων. Δες και αυτήν.

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
let TOTAL=0

# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
       let TOTAL+=LEN
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
[b]                if [[ $NUM -gt 90 ]]; then
                       let NUM-=32
               fi
[/b]                (( ARR[NUM]++ ))
       done
done < $MYFILE

# Ο αριθμός θα είναι μικρότερος από αυτόν που εμφανίζει η wc -m γιατί
# εμείς δεν μετράμε το κάθε newline
echo Sunolikos arithmos xarakthrwn = $TOTAL

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
[b]# χαρακτήρες οι οποίοι είναι 65-90 'A-Z'[/b]

[b]for i in $(seq 65 90); do[/b]
       if [[ ${ARR[$i]} != "" ]]; then
               PCT=${ARR[$i]}
               let PCT*=100
               let PCT/=TOTAL
# Το bash δεν υποστηρίζει πραγματικούς αριθμούς οπότε το 0.60% θα γίνει 0%
# έτσι προσθέτουμε 1 στο κάθε ποσοστό
               let PCT++
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d %d%%\n" ${ARR[$i]} $PCT
       fi
done

exit 0

Δημοσ.
Προσθεσα μια εντολη που μετραει το συνολο των χαρακτηρων στο αρχειο κειμενου.

>
[b]
echo "total = `wc -m $MYFILE | tr -d $MYFILE`"[/b]

 

Το παραπάνω μπορεί επίσης να γίνει και με άλλους τρόπους όπως

>
total = $(wc -m $MYFILE | cut -d " " -f1)

 

Στην προκειμένη περίπτωση όμως δεν χρειάζεται να καταφύγουμε σε

εξωτερικές εντολές μια και ήδη μετράμε το μέγεθος κάθε γραμμής, οπότε

θέλουμε απλά μια μεταβλητή που να προσθέτουμε τα επί μέρους μεγέθη.

 

Όσον αφορά το ποσοστό κάθε γράμματος, εφόσον έχουμε το συνολικό μέγεθος

και τον αριθμό εμφανίσεων του κάθε γράμματος, είναι απλά μια διαίρεση.

 

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
[b]let TOTAL=0[/b]

# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
[b]        let TOTAL+=LEN[/b]
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
               (( ARR[NUM]++ ))
       done
done < $MYFILE

[b]# Ο αριθμός θα είναι μικρότερος από αυτόν που εμφανίζει η wc -m γιατί[/b]
[b]# εμείς δεν μετράμε το κάθε newline[/b]
[b]echo Sunolikos arithmos xarakthrwn = $TOTAL[/b]

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
# χαρακτήρες οι οποίοι είναι 65-90 'A-Z' και 97-122 'a-z'

for i in $(seq 65 90) $(seq 97 122); do
       if [[ ${ARR[$i]} != "" ]]; then
[b]                PCT=${ARR[$i]}[/b]
[b]                let PCT*=100[/b]
[b]                let PCT/=TOTAL[/b]
[b]# Το bash δεν υποστηρίζει πραγματικούς αριθμούς οπότε το 0.60% θα γίνει 0%[/b]
[b]# έτσι προσθέτουμε 1 στο κάθε ποσοστό[/b]
[b]                let PCT++[/b]
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d [b]%d%%[/b]\n" ${ARR[$i]}[b] $PCT[/b]
       fi
done

exit 0

 

Επειδή τα ποσοστά είναι μικρά, η παρακάτω έκδοση δεν κοιτά case και

προσθέτει τις εμφανίσεις πεζών-κεφαλαίων. Δες και αυτήν.

>
#!/bin/bash

echo -e "Give a file to check: \c "

read MYFILE # εδώ αποθηκευεται το ονομα του αρχειου

if [[ $MYFILE == "" ]]; then
       echo Dwse onoma arxeiou
       exit 1
fi

if [ ! -e $MYFILE ]; then
       echo $MYFILE doesnt exit
       exit 2
fi

ARR=()
let TOTAL=0

# Διαβάζουμε την κάθε γραμμή του αρχείου
while read line; do
# Το πλήθος των χαρακτήρων της γραμμής
       LEN=${#line}
       let TOTAL+=LEN
       let LEN--

       for i in $(seq 0 $LEN); do
# Το awk χρησιμοποίησε τα γράμματα ως index π.χ arr[H]
# Για ευκολία εμείς θα χρησιμοποιήσουμε την αντιστοιχία τους σε ASCII
               printf -v NUM "%d" \'${line:$i:1}\'
[b]                if [[ $NUM -gt 90 ]]; then
                       let NUM-=32
               fi
[/b]                (( ARR[NUM]++ ))
       done
done < $MYFILE

# Ο αριθμός θα είναι μικρότερος από αυτόν που εμφανίζει η wc -m γιατί
# εμείς δεν μετράμε το κάθε newline
echo Sunolikos arithmos xarakthrwn = $TOTAL

# Αντί να εμφανίσουμε όλο τον πίνακα, εμφανίζουμε μόνο τους λατινικούς
[b]# χαρακτήρες οι οποίοι είναι 65-90 'A-Z'[/b]

[b]for i in $(seq 65 90); do[/b]
       if [[ ${ARR[$i]} != "" ]]; then
               PCT=${ARR[$i]}
               let PCT*=100
               let PCT/=TOTAL
# Το bash δεν υποστηρίζει πραγματικούς αριθμούς οπότε το 0.60% θα γίνει 0%
# έτσι προσθέτουμε 1 στο κάθε ποσοστό
               let PCT++
               printf -v OCT "%03o" $i
               printf "\\$OCT = %d %d%%\n" ${ARR[$i]} $PCT
       fi
done

exit 0

Δημοσ.

Οντως το 2ο προγραμα ειναι πιο 'εμφανισιμο'. Ευχαριστω και παλι!!

Θα θελα να βρω ενα καλο tutorial ,και αν γινεται ελληνικο, για unix (bash).

Αυτες οι 'μπακαλιες' που εκανα πριν δε βγαζουν πουθενα..

Δημοσ.

Οντως το 2ο προγραμα ειναι πιο 'εμφανισιμο'. Ευχαριστω και παλι!!

Θα θελα να βρω ενα καλο tutorial ,και αν γινεται ελληνικο, για unix (bash).

Αυτες οι 'μπακαλιες' που εκανα πριν δε βγαζουν πουθενα..

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...