Regex 在特定索引处添加分隔符

Regex 在特定索引处添加分隔符,regex,awk,sed,Regex,Awk,Sed,我想在一些索引中为文件的每一行添加一个分隔符 我有一个包含以下数据的文件: 10100100010000 20200200020000 我知道每列的偏移量(2、5和9) 使用此sed命令:sed的/\(.\{2\}\)/&;s/\(.\{6\}\)/&;s/\(.\{11\}\)/&/'myFile 我得到了预期的输出: 10,100,1000,10000 20,200,2000,20000 但是如果有大量的列(~200)和行(300k),速度会非常慢 有没有一个有效的替代方案?第一个解决

我想在一些索引中为文件的每一行添加一个分隔符

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

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

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

我得到了预期的输出:

10,100,1000,10000 
20,200,2000,20000
但是如果有大量的列(~200)和行(300k),速度会非常慢

有没有一个有效的替代方案?

第一个解决方案:使用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
使用
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
解决方案中,我在
substr($0,10,5)
中提取了5个数字/字符,如果您想从第10位开始提取所有字符/数字等,请使用
substr($0,10)
,它将在此处提取所有行的其余字符/数字进行打印

输出如下

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

修改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

如果从后面开始替换,可以使用数字标志
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
gencmd(){
本地arr
#按降序排列参数

IFS=$'\n'arr=($(使用GNU awk对字段宽度进行排序-nr)

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

你需要一个更新版本的gawk for
*
在FIELDWIDTHS的末尾,意思是“剩下什么”,而旧版本只需选择一个大的数字,如
999

最后我尝试了两个解决方案(都有效)RavinderSingh13的第一个解决方案需要约9秒,Aaron的扩展正则表达式解决方案需要约23秒,共有231列和308k。