从字符串中提取每第 n 个字符

Ram*_*esh 6 shell string shell-script

我试图找出这个问题的解决方案。到目前为止,我对这个问题的处理方法如下。

  • 将所有字符附加在一起以使其成为一个长字符串。
  • 完成上述步骤后,删除所有空格或制表符,这样我们就只有一个大字符串。

我能够使用以下命令建立上述步骤。

column -s '\t' inputfile | tr -d '[:space:]'
Run Code Online (Sandbox Code Playgroud)

所以对于这样的输入文件,

1   0   0   0   0   0

0   1   1   1   0   0
Run Code Online (Sandbox Code Playgroud)

应用上述命令后,我的值如下,

100000011100
Run Code Online (Sandbox Code Playgroud)

现在在这个大字符串中,我尝试应用如下方法。

提取每 6字符(如原始 OP 所需),并将其附加到数组元素,直到字符串末尾。

所以基本上,通过上述步骤,我试图将数组元素创建为,

10(1 ST和7字符),01(2和8字符),01(3和9字符),01(4和10字符),00(5和11字符),00(6和12个第一个字符)。

所以我的问题是,我如何提取每个n字符,以便我可以将它们添加到数组中以进一步进行?(在这种情况下,n=6)。

Joh*_*024 5

两条线

这是一个bash生成bash数组的纯解:

s="100000011100"
array=($(
    for ((i=0; i<${#s}-6; i++))
    do
        echo "${s:$i:1}${s:$((i+6)):1}"
    done
    ))
echo "${array[@]}"
Run Code Online (Sandbox Code Playgroud)

这会产生与问题中所示相同的输出:

10 01 01 01 00 00
Run Code Online (Sandbox Code Playgroud)

这里的关键元素是使用 bash 的子字符串扩展。Bash 允许从变量中提取子字符串,例如parameter,通过${parameter:offset:length}。在我们的例子中,偏移量由循环变量确定,i长度始终为1

任意行数的通用解决方案

例如,假设我们的原始字符串有 18 个字符,我们想从 0 到 5 中提取第 i 个、第 i+6 个和第 i+12 个字符。然后:

s="100000011100234567"
array=($(
    for ((i=0; i<6; i++))
    do
        new=${s:$i:1}
        for ((j=i+6; j<${#s}; j=j+6))
        do 
            new="$new${s:$j:1}"
        done
        echo "$new"
    done
    ))

echo "${array[@]}"
Run Code Online (Sandbox Code Playgroud)

这会产生输出:

102 013 014 015 006 007
Run Code Online (Sandbox Code Playgroud)

相同的代码扩展到任意数量的 6 字符行。例如,如果s有三行(18 个字符):

s="100000011100234567abcdef"
Run Code Online (Sandbox Code Playgroud)

然后,输出变为:

102a 013b 014c 015d 006e 007f
Run Code Online (Sandbox Code Playgroud)