如何从文本文件中删除评论

我的文本文件包含一行注释,所有与“/”。 两个正斜杠和一个空格。 这些可能占用整条线或只是线的最后一部分。 每条评论都不会超出它所在的范围。 所以没有/ * * /types注释跨越多行。

简而言之,所有评论都以“// space”开头。 任何以“//空格”开头的东西都应该被删除,并且该行的尾部空格也应该被删除。 领先的空间应该留下来。 任何空白行应该被删除。

示例文件:

// This is a comment x = 1 // This is also a comment after the double slash x = 2 x = 3 // The above is a blank line // Comment on this record but nothing precedes it, so should be deleted. y = 4 // A line with leading spaces that should be kept. z = "//path"; // The first double slashes are not a comment since the space is missing after the "//" // Last comment line. 

结果文件(不包含尾随空格,但保留前导空格:

 x = 1 x = 2 x = 3 y = 4 z = "//path"; 

我可以使用gc file.txt |删除空行 Where-Object {$ _ -ne''}> result.txt。 不过,在阅读“//”注释部分的开始部分时,我遇到了麻烦。

我也尝试findstr,但还没有find如何阅读每一行“/”,然后修剪空间。

我可以编写一个脚本程序来循环遍历文件,并做到这一点,但似乎应该有一种方法来使用简单的一两行PowerShell或bat文件命令来完成它。

什么是最简单的方法(最短的代码量)删除这些评论,同时保持未注释的文件的内容?

由于您似乎将“简单”与“短”等同起来,下面是一个相当简单的解决方案:

 gc .\samplefile.txt|%{$_-replace"(.*)(// .*)",'$1'}|?{$_} 

如果这真的对你很重要:-)

更详细的版本(仍然使用正则表达式):

 Get-Content .\samplefile.txt | Where-Object { -not ([String]::IsNullOrEmpty($_.Trim()) -or $_-match"^\s*// ") } |ForEach-Object { $_ -replace "(.*)(// .*)",'$1' } 

这就是说,我会(个人)去更详细和更易于阅读/维护的解决方案:

要在//之后删除所有内容,最简单的方法是先用String.IndexOf()找到第一个// ,然后用String.Substring()获取第一个部分:

 PS C:\> $CommentedString = "Content // this is a comment" PS C:\> $CommentIndex = $CommentedString.IndexOf('// ') PS C:\> $CommentedString.Substring(0,$CommentIndex) Content 

对于缩进的注释,您还可以使用String.Trim()从字符串的开头和结尾删除空格:

 PS C:\> " // Indented comment" -match '^//' True 

您可以使用ForEach-Object cmdlet遍历每一行并应用以上内容:

 function Remove-Comments { param( [string]$Path, [string]$OutFile ) # Read file, remove comments and blank lines $CleanLines = Get-Content $Path |ForEach-Object { $Line = $_ # Trim() removes whitespace from both ends of string $TrimmedLine = $Line.Trim() # Check if what's left is either nothing or a comment if([string]::IsNullOrEmpty($TrimmedLine) -or $TrimmedLine -match "^// ") { # if so, return nothing (inside foreach-object "return" acts like "coninue") return } # See if non-empty line contains comment $CommentIndex = $Line.IndexOf("// ") if($CommentIndex -ge 0) { # if so, remove the comment $Line = $Line.Substring(0,$CommentIndex) } # return $Line to $CleanLines return $Line } if($OutFile -and (Test-Path $OutFile)){ [System.IO.File]::WriteAllLines($OutFile, $CleanLines) } else { # No OutFile was specified, write lines to pipeline Write-Output $CleanLines } } 

应用于您的示例:

 PS C:\> Remove-Comments D:\samplefile.txt x = 1 x = 2 x = 3 

像许多文本处理问题一样,使用JREPL.BAT是一个功能强大的Windows命令行正则表达式文本处理工具 。 这是纯粹的脚本(混合JScript /批处理),从XP以后的任何Windows机器上本机运行。 完整的文档嵌入在脚本中。

 jrepl "^(.*?)\s*// " "$1!=''?$1:false" /jmatch /f test.txt /o out.txt 

您可以通过指定-作为输出文件来覆盖原始文件:

 jrepl "^(.*?)\s*// " "$1!=''?$1:false" /jmatch /f test.txt /o - 

我测试过了,它给出了你正在寻找的确切的输出。

如果您将该命令放在批处理脚本中,则必须使用call jrepl

在下面的批处理文件做你想要的。 对不起,但没有一个“简单的短代码”的方式来做到这一点…

 @echo off setlocal EnableDelayedExpansion rem Set the maximum number of trailing spaces as a power_of_2-1 value. For example, for 15 spaces: set spcPow2=4 set "spaces= " for /L %%i in (1,1,%spcPow2%) do set "spaces=!spaces!!spaces!" set /A spcPow2-=1 rem Process all lines, excepting empty ones and lines that start with "/" setlocal DisableDelayedExpansion for /F "eol=/ delims=" %%a in (test.txt) do ( set "line=%%a" rem Split line at "// " and get the first part setlocal EnableDelayedExpansion for /F "delims=¡" %%b in ("!line:// =¡!") do ( endlocal set "line=%%b" ) rem Eliminate trailing spaces setlocal EnableDelayedExpansion set spc=0 for /L %%b in (%spcPow2%,-1,0) do ( set /A "newSpc=spc+(1<<%%b)" for %%n in (!newSpc!) do if "!line:~-%%n!" equ "!spaces:~-%%n!" set "spc=%%n" ) if !spc! gtr 0 for %%n in (!spc!) do set "line=!line:~0,-%%n!" rem Show resulting line if defined line echo !line! endlocal ) 

编辑添加新的解决方案

 @set @x=1 // & CScript //nologo //E:JScript "%~F0" < samplefile.txt & goto :EOF WScript.Stdout.Write(WScript.Stdin.ReadAll().replace(/(.*)\/\/ .*/g,"$1")) 

将以前的代码复制到.BAT扩展名的文件中,也就是批处理文件