Comment utiliser awk et grep sur un fichier .txt de 300 Go?

J’ai un énorme fichier .txt, 300 Go pour être plus précis, et je voudrais mettre toutes les chaînes distinctes de la première colonne, qui correspondent à mon modèle dans un fichier .txt différent.

awk '{print $1}' file_name | grep -o '/ns/.*' | awk '!seen[$0]++' > test1.txt 

C’est ce que j’ai essayé, et pour autant que je sache, cela fonctionne très bien mais le problème est qu’après un certain temps, j’obtiens l’erreur suivante:

 awk: program limit exceeded: maximum number of fields size=32767 FILENAME="file_name" FNR=117897124 NR=117897124 

Aucune suggestion?

Le message d’erreur vous indique:

 line(117897124) has to many fields (>32767). 

Vous feriez mieux de le vérifier:

 sed -n '117897124{p;q}' file_name 

Utilisez la cut pour extraire la 1ère colonne:

 cut -d ' ' -f 1 < file_name | ... 

Note : Vous pouvez changer ' ' quel que soit le séparateur de champs. La valeur par défaut est $'\t' .

Le «nombre de champs» est le nombre de «colonnes» dans le fichier d’entrée, donc si l’une des lignes est vraiment longue, cela pourrait entraîner cette erreur.

Je pense que les étapes awk et grep peuvent être combinées en une seule:

 sed -n 's/\(^pattern...\).*/\1/p' some_file | awk '!seen[$0]++' > test1.txt 

Cela pourrait échapper complètement au problème awk (cette commande sed remplace tout texte principal qui correspond au modèle, à la place de la ligne entière, et si elle correspond, imprime la ligne).

Il me semble que votre implémentation awk a une limite supérieure pour le nombre d’enregistrements qu’il peut lire en une seule fois de 117,897,124 . Les limites peuvent varier en fonction de votre implémentation et de votre système d’exploitation.

Une manière sensée d’aborder ce problème consiste peut-être à programmer un script personnalisé qui utilise split pour diviser le fichier volumineux en fichiers plus petits, avec au maximum 100,000,000 enregistrements chacun.


Au cas où vous ne voudriez pas diviser le fichier, vous pourriez peut-être rechercher le fichier de limits correspondant à votre implémentation awk . Peut-être pouvez-vous définir la valeur Number of Records comme étant unlimited , même si je pense que ce n’est pas une bonne idée, car vous pourriez vous retrouver avec beaucoup de ressources …

Si vous avez suffisamment d’espace libre sur le disque (car crée un fichier temp -à-vim

Le message d’erreur indique que votre fichier d’entrée contient trop de champs pour votre implémentation awk. Il suffit de changer le séparateur de champs pour qu’il soit identique au séparateur d’enregistrements et vous n’aurez plus qu’un champ par ligne. Évitez donc ce problème, puis fusionnez le rest des commandes en une seule:

 awk 'BEGIN{FS=RS} {sub(/[[:space:]].*/,"")} /\/ns\// && !seen[$0]++' file_name 

Si cela pose problème alors essayez:

 awk 'BEGIN{FS=RS} {sub(/[[:space:]].*/,"")} /\/ns\//' file_name | sort -u 

Il peut y avoir une solution encore plus simple, mais comme vous n’avez pas envoyé d’échantillons d’échantillons et de résultats attendus, nous ne faisons que deviner.