Regex 用0填充空格/制表符分隔的空列
我有一个巨大的文件,作为输出,有些列没有值,我需要用0填充这些列以进行进一步分析。我可以用空格或制表符分隔列,现在可以看到下面是用制表符分隔的Regex 用0填充空格/制表符分隔的空列,regex,perl,file,sed,awk,Regex,Perl,File,Sed,Awk,我有一个巨大的文件,作为输出,有些列没有值,我需要用0填充这些列以进行进一步分析。我可以用空格或制表符分隔列,现在可以看到下面是用制表符分隔的 这实际上是CSV解析器的工作,但如果它必须是正则表达式,并且在引用的CSV条目中没有选项卡,则可以搜索 (^|\t)(?=\t|$) 并替换为 $10 因此,在Perl中: (ResultString = $subject) =~ s/( # Match either... ^ # the start of the line (pr
这实际上是CSV解析器的工作,但如果它必须是正则表达式,并且在引用的CSV条目中没有选项卡,则可以搜索
(^|\t)(?=\t|$)
并替换为
$10
因此,在Perl中:
(ResultString = $subject) =~
s/( # Match either...
^ # the start of the line (preferably)
| # or
\t # a tab character
) # remember the match in backreference no. 1
(?= # Then assert that the next character is either
\t # a(nother) tab character
| # or
$ # the end of the line
) # End of lookahead assertion
/${1}0/xg;
这将改变
1 2 4 7 8
2 3 5 6 7
进入
对于选项卡分隔的文件,此AWK代码段实现了以下功能:
BEGIN { FS = "\t"; OFS="\t" }
{
for(i = 1; i <= NF; i++) {
if(!$i) { $i = 0 }
}
print $0
}
BEGIN{FS=“\t”;OFS=“\t”}
{
对于(i=1;i在重新阅读原始帖子后删除我的答案。没有选项卡作为数据,只有delimeters。如果没有数据,将使用双delimeter对齐列。
这不可能是其他方式。因此,如果有一个delimeter,它将分隔两个空字段。“=1个空字段,“\t”=2个空字段。我现在知道了
蒂姆·皮耶茨克一直都有正确的答案。+1代表他。
它也可以写成s/(?:^ |)(?这里有一个sed
解决方案。请注意,sed
的一些版本不喜欢\t
sed 's/^\t/0\t/;:a;s/\t\t/\t0\t/g;ta;s/\t$/\t0/' inputfile
或
说明:
s/^\t/0\t/ # insert a zero before a tab that begins a line
:a # top of the loop
s/\t\t/\t0\t/g # insert a zero between a pair of tabs
ta # if a substitution was made, branch to the top of the loop
s/\t$/\t0/ # insert a zero after a tab that ends a line
如果且仅当您的数据仅包含数字,并且您有明确定义的字段分隔符FS
,则可以使用以下技巧:
awk 'BEGIN{FS=OFS="\t"}{for(i=1;i<=NF;++i) $i+=0}1' file
awk'BEGIN{FS=OFS=“\t”}{for(i=1;如果空列在一行的开头或结尾,即不在两个制表符之间,这也会起作用吗?是的。我在一个小的(3列)上测试过它文件,一个完全填充的行,中间有一个缺失的值,一个在开始时有缺失值,一个在末尾缺失,它正确地处理所有四条线。<代码> 0美元<代码>是多余的:<代码>打印< /代码>就足够了。这.“…如果必须是正则表达式…”原始海报从未提到使用正则表达式?@mfontani:Oops.当然…@plusplus:是的,他使用了,这是他使用的第一个标记。@Tim Pietzcker,perl-p-e“s/(^ | \t)(?=\t |$)/${1}0/xg”文件,似乎不起作用,有什么想法吗?零只是放在列成员旁边。对不起,我不知道perl(我从RegexBuddy那里得到了代码片段,它将我的regex翻译成了Perl代码),所以我不知道哪里出了问题。它确实希望文件是以制表符分隔的。你能在你的问题中发布你的文件的摘录(而不是截图)吗?一两行就足够了。@Tim Pietzcker,Perl-p-e“s/(^ |\t)(?=\t |$)/${1}\t0/g”工作正常。输出由一个工具给出,它有制表符和逗号选项。这里-i.txt的功能是什么?我的文件列号也可以根据需要更改output@berkay-c:\>perl-h将为您提供所有开关。-i[extension]是就地编辑,其中[extension]被添加到您的输入文件名中(这里是它的'd.txt')作为输入文件(正在修改)的“备份”文件名。您始终可以将其作为Perl程序运行,并传入文件名和编号。在这种情况下,正则表达式将是s!(?:^|(?谢谢,但我对正则表达式有问题。s后面应该跟“/,s///这是windows风格吗?@berkay在unix上,您应该使用单引号。这是新的正则表达式,如果没有任何效果:perl-pe的s/(?:^|(?现在它可以工作了,但也可以检查接受的答案,这更容易理解。谢谢sln。+1只是一个问题,您是否检查了编辑器中的最后一个空白列?是列数据(不是delimeter)一个实际的\t?为了澄清,如果出现类似a\t\t\tb
的情况,则需要一个循环。正则表达式匹配从不重叠。因此,如果循环不可用,a\t\t\tb
将更改为a\t0\t\tb
,而不是a\t0\t0\tb
s/^\t/0\t/ # insert a zero before a tab that begins a line
:a # top of the loop
s/\t\t/\t0\t/g # insert a zero between a pair of tabs
ta # if a substitution was made, branch to the top of the loop
s/\t$/\t0/ # insert a zero after a tab that ends a line
awk 'BEGIN{FS=OFS="\t"}{for(i=1;i<=NF;++i) $i+=0}1' file