# How to insert newline characters every N chars into a long string [duplicate]

Using common bash tools as part of a shell script, I want to repeatedly insert a newline char ('\n') into a long string at intervals of every N chars.

For example, given this string, how would I insert a newline char every 20 chars?

head -n 50 /dev/urandom | tr -dc A-Za-z0-9


Example of the results I am trying to achieve:

ZL1WEV72TTO0S83LP2I2
MTQ8DEIU3GSSYJOI9CFE
6GEPWUPCBBHLWNA4M28D
P2DHDI1L2JQIZJL0ACFV
UDYEK7HN7HQY4E2U6VFC
RH68ZZJGMSSC5YLHO0KZ
94LMELDIN1BAXQKTNSMH
0DXLM7B5966UEFGZENLZ
4917Y741L2WRTG5ACFGQ
GRVDVT3CYOLYKNT2ZYUJ
EAVN1EY4O161VTW1P3OY
Q17T24S7S9BDG1RMKGBX
WOZSI4D35U81P68NF5SB
HH7AOYHV2TWQP27A40QC
QW5N4JDK5001EAQXF41N
FKH3Q5GOQZ54HZG2FFZS
Q89KGMQZ46YBW3GVROYH
AIBOU8NFM39RYP1XBLQM
YLG8SSIW6J6XG6UJEKXO


A use-case is to quickly make a set of random passwords or ID's of a fixed length. The way I did the above example is:

for i in {1..30}; do head /dev/random | tr -dc A-Z0-9 | head -c 20 ; echo ''; done


However, for learning purposes, I want to do it a different way. I want to start with an arbitrarily long string and insert newlines, thus breaking one string into multiple small strings of fixed char length.

## marked as duplicate by Archemar, msp9011, andcoz, Jeff Schaller, ChristopherDec 19 '18 at 16:48

• fold -w 20 works. I agree, you should make it an answer. – BugBuddy Dec 18 '18 at 23:30
• – Sergiy Kolodyazhnyy Dec 19 '18 at 7:36
• The standard utilities are not "bash tools". – Kusalananda Dec 19 '18 at 8:11

The venerable fold command ("written by Bill Joy on June 28, 1977") can wrap lines:

$printf "foobarzot\n" | fold -w 3 foo bar zot  However, there are some edge cases BUGS Traditional roff(7) output semantics, implemented both by GNU nroff and by mandoc(1), only uses a single backspace for backing up the previous character, even for double-width characters. The fold backspace semantics required by POSIX mishandles such backspace-encoded sequences, breaking lines early. The fmt(1) utility provides similar functionality and does not suffer from that problem, but isn't standardized by POSIX. so if your input has backspace characters you may need to filter or remove those $ printf "a\bc\bd\be\n" | col -b | fold -w 1
e
$printf "a\bc\bd\be\n" | tr -d "\b" | fold -w 1 a c d e  I like the fold answer but just in case you want with sed, here it is: sed 's/.\{20\}/&\ /g' filename  You can use -i for in-place insertion. • thanks. I voted your answer up, but I like the fold solution too. – BugBuddy Dec 19 '18 at 0:48 If you have the contents in a variable, such as: var=$(head -n 50 /dev/urandom | tr -dc A-Za-z0-9)


Then you could use a bash loop over the length of the variable in chunks of 20, printing out each chunk:

for((start=1;start < ${#var}; start += 20)); do printf '%s\n' "${var:start:20}"; done


If you want them as individual variables, consider assigning the output to an array:

readarray -t passwords < <(for((start=1;start < ${#var}; start += 20)); do printf '%s\n' "${var:start:20}"; done)


Instead of doing that tr -dc thing to get rid of non-printable chars, I would just use base64 from coreutils:

$base64 -w20 /dev/urandom | head -8 ckXkWvb0zJknz2zi4fRS 3Jv0dDbKiX8fef7SOfbH QJySlGUzzhi32wvrGliK YEiuz6v+EFaRYRMjvnJq HCXIPiP9wmgONLRqm9uK iHYwo5xIs8gGjQQEQBeX 8NkL4EkmOAHdmWhGvZYl AcxD2DaTq2TZRsDL+UMx  If the + and / are problem you can replace them: $ base64 -w20 /dev/urandom | tr +/ pq | head -8
zr7MgiEr7xBd7h9ihK30
IRNvDuT2H9HsHVq9yFqh
S1cihgfAInjfFspMNXVC
qUUwGErD7nZqtzQtLOo7
DNDp4TVWvHmbEh7HLDGX
GtqqDdEoceY8m5U7FGu0
TvGtTukm6Whr7VHN1mZG
DW5TUH525IA52zLKYACV