résultat final de la commande bash avec un point (.)

J’ai un script bash qui écrit et sortinge les informations de / etc / passwd ici

export FT_LINE1=13 export FT_LINE2=23 cat /etc/passwd | grep -v "#" | awk 'NR%2==1' | cut -f1 -d":" | rev | sort -r | awk -v l1="$FT_LINE1" -v l2="$FT_LINE2" 'NR>=l1 && NR<=l2' | tr '\n' ',' | sed 's/, */, /g' 

Le résultat est cette liste

 sstq_, sorebrek_brk_, soibten_, sirtsa_, sergtsop_, sec_, scodved_, rlaxcm_, rgmecived_, revreswodniw_, revressta_, 

Comment puis-je remplacer la dernière virgule par un point (.)? Je veux que ça ressemble à ça

 sstq_, sorebrek_brk_, soibten_, sirtsa_, sergtsop_, sec_, scodved_, rlaxcm_, rgmecived_, revreswodniw_, revressta_. 

Il y a beaucoup de chemin vers de nombreux tuyaux dans votre commande, certains peuvent être supprimés.

Comme expliqué dans le commentaire cat | grep cat | grep est une mauvaise habitude !!! En général, le cat | cmd cat | cmd devrait être remplacé par cmd ou cmd < FILE selon le type d'arguments acceptés par votre commande.

Sur un fichier de taille de quelques Go à traiter, vous sentirez déjà la différence.

Ceci étant dit, vous pouvez effectuer tout le traitement sans utiliser un seul tuyau en utilisant awk par exemple:

 awk -v l1="$FT_LINE1" -v l2="$FT_LINE2" 'function reverse(s){p=""; for(i=length(s); i>0; i--){p=p substr(s,i,1);}return p;}BEGIN{cmp=0; FS=":"; ORS=","}!/#/{cmp++;if(cmp%2==1) a[cmp]=reverse($1);}END{asort(a);for(i=length(a);i>0;i--){if((length(a)-i+1)>=l1 && (length(a)-i)<=l2){if(i==1){ORS=".";}print a[i];}}}' /etc/passwd 

Explications:

 # BEGIN rule(s) BEGIN { cmp = 0 #to be use to count the lines since NR can not be used directly FS = ":" #file separator : ORS = "," #output record separator , } # Rule(s) ! /#/ { #for lines that does not contain this char cmp++ if (cmp % 2 == 1) { a[cmp] = reverse($1) #add to an array the reverse of the first field } } # END rule(s) END { asort(a) #sort the array and process it in reverse order for (i = length(a); i > 0; i--) { # apply your range conditions if (length(a) - i + 1 >= l1 && length(a) - i <= l2) { if (i == 1) { #when we reach the last character to print, instead of the comma use a dot ORS = "." } print a[i] #print the array element } } } # Functions, listed alphabetically #if the reverse operation is necessary then you can use the following function that will reverse your strings. function reverse(s) { p = "" for (i = length(s); i > 0; i--) { p = p substr(s, i, 1) } return p } 

Si vous n'avez pas besoin d' reverse partie, vous pouvez simplement la supprimer du script awk .

Au final, pas un seul tuyau n'est utilisé !!!

Vous pouvez append:

 | sed 's/,$/./' 

(où $ signifie “fin de ligne”).