我的文本文件包含一行注释,所有注释都是" //"。两个正斜杠和一个空格。这些可能占据整条线,也可能只占线的最后一部分。每条评论都不会延伸到它所在的界限之外。所以没有/ * * /类型注释跨越多行。
简单来说,所有评论都以" // space"开头。在线的任何地方。任何以" // 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。但是,我只是在阅读" //"的一行的开头部分时遇到了麻烦。评论部分。
我也尝试过findtr但是还没找到如何读取每一行到#34; //"然后修剪空格。
我可以编写一个脚本程序来遍历文件并执行此操作,但似乎应该有一种方法可以使用简单的一行或两行PowerShell或bat文件命令来完成它。
在保留文件的未注释内容的同时删除这些注释的最简单方法(最短的代码量)是什么?
答案 0 :(得分:2)
因为你似乎等同于" easy"使用"短",这是一个相当简单的解决方案:
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
答案 1 :(得分:1)
与许多文本处理问题一样,使用JREPL.BAT - a powerful regex text processing utility for the Windows command line有一个简单的解决方案。它是纯脚本(混合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
答案 2 :(得分:1)
@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的文件中,也就是说,它是批处理文件!