如何在长字符串中每N个字符插入换行符

如何在长字符串中每N个字符插入换行符

使用常见的 bash 工具作为 shell 脚本的一部分,我想以每 N 个字符的间隔重复将换行符 ('\n') 插入到长字符串中。

例如,给定这个字符串,我如何每 20 个字符插入一个换行符?

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

我试图实现的结果示例:

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

一个用例是快速生成一组固定长度的随机密码或 ID。我上面例子的做法是:

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

但是,出于学习目的,我想以不同的方式进行。我想从任意长的字符串开始并插入换行符,从而将一个字符串分成多个固定字符长度的小字符串。

答案1

尊者fold命令(“由 Bill Joy 于 1977 年 6 月 28 日编写”)可以换行:

$ printf "foobarzot\n" | fold -w 3
foo
bar
zot

然而,也有一些边缘情况

错误 传统的 roff(7) 输出语义由 GNU nroff 和 mandoc(1) 实现,仅使用单个退格键来备份前一个字符,即使对于双角字符也是如此。 POSIX 所需的折叠退格语义错误地处理了此类退格编码序列,导致过早断行。 fmt(1) 实用程序提供类似的功能,并且不会遇到该问题,但未由 POSIX 标准化。

因此,如果您的输入包含退格字符,您可能需要过滤或删除这些字符

$ 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

答案2

我喜欢这个fold答案,但以防万一你想要sed,这里是:

sed 's/.\{20\}/&\
/g' filename

您可以用于-i就地插入。

答案3

如果变量中有内容,例如:

var=$(head -n 50 /dev/urandom | tr -dc A-Za-z0-9)

然后,您可以在变量的长度上使用 bash 循环(以 20 块为单位),打印出每个块:

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

如果您希望它们作为单独的变量,请考虑将输出分配给数组:

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

答案4

我不会这样做来tr -dc摆脱不可打印的字符,而是只使用base64coreutils 中的内容:

$ base64 -w20 /dev/urandom | head -8
ckXkWvb0zJknz2zi4fRS
3Jv0dDbKiX8fef7SOfbH
QJySlGUzzhi32wvrGliK
YEiuz6v+EFaRYRMjvnJq
HCXIPiP9wmgONLRqm9uK
iHYwo5xIs8gGjQQEQBeX
8NkL4EkmOAHdmWhGvZYl
AcxD2DaTq2TZRsDL+UMx

如果+/出现问题,您可以更换它们:

$ base64 -w20 /dev/urandom | tr +/ pq | head -8
zr7MgiEr7xBd7h9ihK30
IRNvDuT2H9HsHVq9yFqh
S1cihgfAInjfFspMNXVC
qUUwGErD7nZqtzQtLOo7
DNDp4TVWvHmbEh7HLDGX
GtqqDdEoceY8m5U7FGu0
TvGtTukm6Whr7VHN1mZG
DW5TUH525IA52zLKYACV

相关内容