web-dev-qa-db-fra.com

Quel est un moyen pratique de lister chaque caractère utilisé dans un fichier (Bash) (Regex)

Comment puis-je transformer ceci:

Johnny's penguin, (Tuxie), likes the following foods: French fries, and beef.

Pour ça:

 abcdefghiklnoprstuwFJT',():.

(Ce sont les caractères totaux utilisés dans l'entrée)

Veuillez noter que les petits caractères de casse "jmqvz" ne figuraient pas dans la phrase d'entrée et ne sont donc pas sortis.

L'ordre n'est pas important, mais des minuscules, puis des majuscules, puis les caractères spéciaux seront préférés.

Je suis certain d’avoir besoin de sed/awk/etc. pour cela, mais je n'ai rien trouvé de semblable après des recherches approfondies.

3
TuxForLife

Vous pouvez utiliser une combinaison de sed et sort:

_$ echo "Johnny's penguin, (Tuxie), likes the following foods: French fries, and beef." | 
>  sed 's/./&\n/g' | LC_COLLATE=C sort -u | tr -d '\n'
 '(),.:FJTabcdefghiklnoprstuwxy
_

sort effectue un tri lexicographique, alors consultez man 7 ascii pour voir comment les caractères seront ordonnés.

Explication:

  • _sed 's/./&\n/g'_ - ajoute une nouvelle ligne après chaque caractère, puisque sort (généralement) effectue un tri ligne par ligne
  • _LC_COLLATE=C_ définit le style de classement sur C (voir Que fait “LC_ALL = C”? )
  • _sort -u_: trie l'entrée et n'imprime que les entrées uniques
  • _tr -d '\n'_ supprime toutes les nouvelles lignes supplémentaires.

Si vous souhaitez ne conserver que des caractères visibles:

_$ echo "Johnny's penguin, (Tuxie), likes the following foods: French fries, and beef." | 
> tr -cd '[[:graph:]]' | sed 's/./&\n/g' | LC_COLLATE=C sort -u | tr -d '\n'
_
  • _tr -cd '[[:graph:]]'_ supprime tout sauf les caractères visibles.
11
muru

Vous pouvez imprimer chaque caractère d'un fichier sur une ligne distincte à l'aide de fold -w1, puis trier le résultat et éliminer les doublons avec sort -u (ou sort | uniq):

$ cat test 
Johnny's penguin, (Tuxie), likes the following foods: French fries, and beef.
$ fold -w1 test | sort -u

,
:
.
'
(
)
a
b
c
d
e
f
F
g
h
i
J
k
l
n
o
p
r
s
t
T
u
w
x
y

Ensuite, vous pouvez à nouveau transformer cela en une seule ligne, par exemple avec un paste -sd "" -:

$ fold -w1 test | sort -u | paste -sd "" -
 ,:.'()abcdefFghiJklnoprstTuwxy
8
Nykakin

Ooh, amusant! Voici quelques façons. Le plus simple (fold) a déjà été donné, mais voici un moyen de le développer pour donner également les comptes pour chaque caractère:

$ fold -w 1 file | LC_ALL=C sort  | uniq -c
 11  
  2 "
  1 '
  1 (
  1 )
  3 ,
  1 .
  1 :
  1 F
  1 J
  1 T
  1 a
  1 b
  2 c
  2 d
  9 e
  4 f
  2 g
  4 h
  5 i
  1 k
  3 l
  7 n
  6 o
  1 p
  2 r
  4 s
  1 t
  2 u
  1 w
  1 x
  1 y

L'utilisation de LC_ALL=C définit les paramètres régionaux sur C pour la commande sort, ce qui signifie que les CAPITALES sont triées avant les minuscules, comme vous l'avez demandé. Pour tout avoir sur la même ligne sans compter les occurrences, mais avec le même ordre de tri, vous pouvez le faire

$ echo $(fold -w 1 file | LC_ALL=C sort -u | tr -d '\n')
"'(),.:FJTabcdefghiklnoprstuwxy

Vous pouvez aussi utiliser Perl:

$ Perl -lne '$k{$_}++ for split(//); END{print sort keys(%k)}' file
"'(),.:FJTabcdefghiklnoprstuwxy

Enfin, voici une manière d'afficher les caractères spéciaux tels que les tabulations, les nouvelles lignes et les retours à la ligne:

$ echo $(od -c file | grep -oP "^\d+ +\K.*" | tr -s ' ' '\n' | 
    LC_ALL=C sort -u | tr -d '\n')
"'(),.:FJT\n\r\tabcdefghiklnoprstuwxy
          ------
            |-------------> special characters
3
terdon

Supprimez simplement les caractères en double de la chaîne d'entrée. set fonction dans python créerait un ensemble d'éléments sans doublons. c'est-à-dire que set('ssss') vous donnera un seul s.

À travers python3

$ cat file
Johnny's penguin, (Tuxie), likes the following foods: French fries, and beef.

$ python3 -c 'import sys
with open(sys.argv[1]) as f:
    for line in f:
        print("".join(sorted(set(line))))' file
 '(),.:FJTabcdefghiklnoprstuwxy

Si vous souhaitez supprimer les caractères en double présents dans le fichier entier, vous pouvez essayer ceci.

$ python3 -c 'import sys
with open(sys.argv[1]) as f:
    print("".join(sorted(set(f.read()))))' file
2
Avinash Raj