Comment diviser la chaîne en lignes avec une largeur spécifique en utilisant les commandes unix? Lorsque la chaîne d’entrée est infinie?

Je veux convertir

Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He... 

à

 Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello. Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He ..., 

où la largeur est de 80 caractères.

J’ai d’abord pensé que je pouvais utiliser sed . (Laissez-moi vous expliquer avec 5 caractères au lieu de 80 caractères pour clarifier.)

 echo "longlonglonglonglonglonglonglonglonglonglonglong" | sed 's/\(.\{5\}\)/\1\'$'\n/g' 

donne

 longl onglo nglon glong longl onglo nglon glong longl ong 

comme je veux. Cependant, je ne pouvais pas utiliser cette façon lorsque la chaîne d’entrée dure pour toujours.

 while true; do; echo -n "Hello."; done | sed 's/\(.\{5\}\)/\1\'$'\n/g' 

La commande ci-dessus ne fonctionne pas. J’ai aussi essayé d’utiliser perl , mais en vain. ( perl -pe 's/(.{5})/$1\n/g' ) J’ai donc abandonné la résolution des commandes Unix et écrit un petit programme en C.

 #include  int main(int argc, char *argv[]) { int i = 0, ch; while ((ch = fgetc(stdin)) != EOF) { putchar((char)ch); i += 1; if (ch == '\n') { i = 0; } if (i >= 80) { printf("\n"); i = 0; } } return 0; } 

Le programme fonctionne bien pour moi. Donc, la question est, comment puis-je diviser les longues chaînes de caractères longues (probablement infinies) en lignes en utilisant les commandes unix?

fold peut être votre ami:

 $ fold -w 80 file Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello. Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He ... $ fold -w 20 file Hello.Hello.Hello.He llo.Hello.Hello.Hell o.Hello.Hello.Hello. Hello.Hello.Hello.He llo.Hello.Hello.Hell o.Hello.Hello.Hello. Hello.Hello.Hello.He llo.Hello.Hello.Hell o.Hello.Hello.Hello. Hello.Hello.Hello.He llo.Hello.Hello.Hell o.Hello.Hello.Hello. Hello.Hello.Hello.He llo.Hello.Hello.Hell o.Hello.Hello.Hello. Hello.Hello.Hello.He ... 

De l’ man fold :

fold – enroulez chaque ligne pour l’adapter à la largeur spécifiée

-w , –width = WIDTH

utiliser des colonnes WIDTH au lieu de 80

Donc, en fait, le fold file est le même que le fold -w 80 file

Vous pouvez utiliser un liner,

 perl -lpe 'BEGIN{ $/ = \80 }' file 

De peldoc perlvar

$ /

Le séparateur d’enregistrement en entrée, newline par défaut. [..] Définir $ / sur une référence à un entier, un scalaire contenant un entier ou un scalaire convertible en entier tentera de lire les enregistrements au lieu de lignes, la taille maximale d’enregistrement étant le nombre entier de caractères référencé

essayez l’option -u

-u (–unbuffered)

Mettre en mémoire tampon les entrées et les sorties aussi peu que possible. (Ceci est particulièrement utile si l’entrée provient de la “queue -f”, et que vous souhaitez voir la sortie transformée dès que possible.)

 sed -u 's/\(.\{5\}\)/\1\'$'\n/g' 

Vous pouvez aussi essayer le code ci-dessous,

 $ perl -0777pe 's/(.{80})/\1\n/g' file Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello. Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He ...