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
cat
est une mauvaise habitude !!! En général, le cat
cat
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”).