我想在文件的每一行的某些索引中添加定界符。
我有一个包含数据的文件:
10100100010000
20200200020000
我知道每列(2、5和9)的偏移量
使用以下sed命令:sed 's/\(.\{2\}\)/&,/;s/\(.\{6\}\)/&,/;s/\(.\{11\}\)/&,/' myFile
我得到了预期的输出:
10,100,1000,10000
20,200,2000,20000
但是具有大量列(〜200)和行(300k)的速度确实很慢。
有没有有效的选择?
答案 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
。