linux - 从一个位置开始将一个长字符串包装成多行

标签 linux file shell awk

我有一个看起来像这样的文件:

FirstSentences1  bfjkjhdfhizhfzibfkjezfzfiuzehfizdjfldfsdfsljfklj
SecondSentences2 fjlskdjfjoijrgeojrgijgoejrgrjgiorjofgjeirjgoergd
.
.
.
NthhhSentencesN  klkdlffjsldfsljflsfjlskfjldkjflsfjlfkdjfdfjojjij

我必须得到以下输出:

FirstSentences1  bfjkjhdfhizhfzibfkje
FirstSentences1  zfzfiuzehfizdjfldfsd
FirstSentences1  fsljfklj
SecondSentences2 fjlskdjfjoijrgeojrgi
SecondSentences2 jgoejrgrjgiorjofgjei
SecondSentences2 rjgoergd
.
.
.
NthhhSentencesN  klkdlffjsldfsljflsfj
NthhhSentencesN  lskfjldkjflsfjlfkdjf
NthhhSentencesN  dfjojjij

解释:

例如第一行:

FirstSentences1  bfjkjhdfhizhfzibfkjezfzfiuzehfizdjfldfsdfsljfklj

我们获取字符串 "bfjkjhdfhizhfzibfkjezfzfiuzehfizdjfldfsdfsljfklj"并在长度等于 20 时将其包装

你知道得到这个的方法吗?

最佳答案

您可以使用一个利用字符串索引 和嵌套循环的简短脚本来做到这一点:

#!/bin/bash

declare -i len=${2:-20}     ## take length as 2nd arg (filename is 1st)

while read -r line; do      ## read each line
    while [ ${#line} -gt 0 ]; do            ## if characters remain
        printf "%s\n" "${line:0:$((len))}"  ## print len chars
        line="${line:$((len))}"             ## strip len chars from line
    done
done < "$1"

示例输入文件

$ cat dat/longsent.txt
bfjkjhdfhizhfzibfkjezfzfiuzehfizdjfldfsdfsljfklj
fjlskdjfjoijrgeojrgijgoejrgrjgiorjofgjeirjgoergd

示例使用/输出

默认值 包装 20-chars每行:

$ bash wrap.sh dat/longsent.txt
bfjkjhdfhizhfzibfkje
zfzfiuzehfizdjfldfsd
fsljfklj
fjlskdjfjoijrgeojrgi
jgoejrgrjgiorjofgjei
rjgoergd

包装在 10每行字符:

$ bash wrap.sh dat/longsent.txt 10
bfjkjhdfhi
zhfzibfkje
zfzfiuzehf
izdjfldfsd
fsljfklj
fjlskdjfjo
ijrgeojrgi
jgoejrgrjg
iorjofgjei
rjgoergd

注意:您应该验证 len大于 0 , 你可以添加 || test -n "$line"到第一个 while 子句以适应在最后一行结束的非 POSIX 行(为简洁起见省略)。


包括行前缀

如果您的数据文件包含前缀(例如 FirstSentence1...)并且您需要在输出中包含这些前缀,您只需添加 prefix 的读取即可之前line并输出 prefix (具有一些合理的字段宽度,左对齐)在每条换行之前。例如:

#!/bin/bash

declare -i len=${2:-20}     ## take length as 2nd arg (filename is 1st)
declare -i wdth=22          ## set min field width for prefix (so cols align)

while read -r prefix line; do      ## read each line
    while [ ${#line} -gt 0 ]; do   ## if characters remain
        ## print len chars w/prefix width set to wdth, left-justified
        printf "%-*s %s\n" $wdth "$prefix" "${line:0:$((len))}"
        line="${line:$((len))}"    ## strip len chars from line
    done
done < "$1"

带前缀的示例输入文件

$ cat dat/longsentpfx.txt
FirstSentence1   bfjkjhdfhizhfzibfkjezfzfiuzehfizdjfldfsdfsljfklj
SecondSentences2 fjlskdjfjoijrgeojrgijgoejrgrjgiorjofgjeirjgoergd

示例使用/输出

$ bash wrap.sh dat/longsentpfx.txt
FirstSentence1         bfjkjhdfhizhfzibfkje
FirstSentence1         zfzfiuzehfizdjfldfsd
FirstSentence1         fsljfklj
SecondSentences2       fjlskdjfjoijrgeojrgi
SecondSentences2       jgoejrgrjgiorjofgjei
SecondSentences2       rjgoergd

$ bash wrap.sh dat/longsentpfx.txt 10
FirstSentence1         bfjkjhdfhi
FirstSentence1         zhfzibfkje
FirstSentence1         zfzfiuzehf
FirstSentence1         izdjfldfsd
FirstSentence1         fsljfklj
SecondSentences2       fjlskdjfjo
SecondSentences2       ijrgeojrgi
SecondSentences2       jgoejrgrjg
SecondSentences2       iorjofgjei
SecondSentences2       rjgoergd

如果您还有其他问题,请告诉我。

注意:将宽度设置为刚好超过最长的一个字符 prefix ,您需要阅读所有 prefix实际写入换行之前的值以找到最长的宽度,然后添加 +1 .如果你的数据文件很短,你可以将前缀和行读入一对索引数组并首先从前缀数组中扫描长度,如果数据文件很大,你可以扫描文件两次(不是最优),或者您可以像上面那样设置一些预先确定的宽度。

关于linux - 从一个位置开始将一个长字符串包装成多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38214544/

相关文章:

c - 将文件中的内容添加到链表

bash - Shell:连接到网站并访问字段

linux - 从一个单位为 2 行的文件中随机选择(单位)。

python - 如何在纯python中的Windows上获取父 shell 的路径?

c - windows上的代码文件如何与WSL/linux同步?

java - 从 Java 程序打开浏览器窗口

C++ boost/asio 客户端不连接到服务器

gcc - 在 Linux 上编译/链接电子文本编辑器时出错

C++ : Read random line from text file

java - Fs 只读存档 FilesystemException