簡體   English   中英

如何從文本文件中刪除評論

[英]How to remove comments from text file

我的文本文件包含一行注釋,所有注釋都帶有“ //”。 兩個正斜杠和一個空格。 這些可能占用整條線,也可能只占用一行的最后一部分。 每個注釋都不會超出其所在的行。 因此,沒有/ * * /鍵入注釋跨越多行。

簡單來說,所有注釋都以“ // 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。 但是,我在讀取一行的開始部分到“ //”注釋部分時遇到了麻煩。

我也嘗試過findstr,但是還沒有找到如何讀取每一行直到“ //”,然后修剪掉空格。

我可以編寫一個腳本程序來遍歷文件並執行此操作,但是似乎應該有一種方法可以使用簡單的一兩行powershell或bat file命令來完成它。

在保留文件中未注釋內容的同時刪除這些注釋的最簡單方法(最短代碼量)是什么?

由於您似乎將“簡單”等同於“簡短”,因此,這是一個非常簡單的解決方案:

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的簡單解決方案-J功能強大的regex文本處理實用程序,適用於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的文件中,即它是一個批處理文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM