在特定索引处添加定界符

时间:2019-02-26 16:11:48

标签: regex awk sed

我想在文件的每一行的某些索引中添加定界符。

我有一个包含数据的文件:

10100100010000
20200200020000

我知道每列(2、5和9)的偏移量

使用以下sed命令:sed 's/\(.\{2\}\)/&,/;s/\(.\{6\}\)/&,/;s/\(.\{11\}\)/&,/' myFile

我得到了预期的输出:

10,100,1000,10000 
20,200,2000,20000

但是具有大量列(〜200)和行(300k)的速度确实很慢。

有没有有效的选择?

4 个答案:

答案 0 :(得分:8)

第一个解决方案: 请使用GNU awk,请尝试以下方法。

awk -v OFS="," '{$1=$1}1' FIELDWIDTHS="2 3 4 5"  Input_file

第二个解决方案: :使用sed尝试执行以下操作。

sed 's/\(..\)\(...\)\(....\)\(.....\)/\1,\2,\3,\4/' Input_file

第三种解决方案: 使用awk的{​​{1}}解决方案。

substr

在上述awk 'BEGIN{OFS=","} {print substr($0,1,2) OFS substr($0,3,3) OFS substr($0,6,4) OFS substr($0,10,5)}' Input_file 解决方案中,我想在substr中输入5位数字/字符,以防万一您要从第10位开始使用所有字符/数字等,请使用substr($0,10,5),它将休息要打印的所有行字符/数字。

输出如下。

substr($0,10)

答案 1 :(得分:5)

修改sed命令以使其一次性添加所有分隔符可能会使其性能更好:

sed 's/^\(.\{2\}\)\(.\{3\}\)\(.\{4\}\)/\1,\2,\3,/' myFile

或带有扩展的正则表达式:

sed -E 's/(.{2})(.{3})(.{4})/\1,\2,\3,/' myFile

输出:

10,100,1000,10000
20,200,2000,20000

答案 2 :(得分:1)

如果从背面开始替换,则可以在s上使用数字标志来指定要在其后添加逗号的任何字符:

$ sed 's/./&,/9;s/./&,/5;s/./&,/2' myFile
10,100,1000,10000
20,200,2000,20000

您可以通过使用printf语句构建命令来进一步自动化该操作:

printf -v cmd 's/./&,/%d;' 9 5 2
sed "$cmd" myFile

甚至将其包装在一个小的shell函数中,因此我们不必关心以相反的顺序列出列:

gencmd() {
    local arr
    # Sort arguments in descending order
    IFS=$'\n' arr=($(sort -nr <<< "$*"))
    printf 's/./&,/%d;' "${arr[@]}"
}

sed "$(gencmd 2 5 9)" myFile

答案 3 :(得分:1)

使用GNU awk的FIELDWIDTHS:

$ awk -v FIELDWIDTHS='2 3 4 *' -v OFS=',' '{$1=$1}1' file
10,100,1000,10000
20,200,2000,20000

您需要在FIELDWIDTHS末尾的*上使用更高版本的gawk,以表示“剩下的东西”,而较旧的版本只需选择较大的数字,例如999