根据匹配的文本/参数修改txt文件中的重复单词/文本

时间:2019-05-18 13:25:04

标签: .net json regex batch-file vbscript

我有一个文本文件,其中包含:

[{
      "Subtitle": {
        "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
        },
        "SubtitleList": [
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 0
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 1
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 3,
            "Offset": 0,
            "Track": 2
        }]
    }
}]

但是,相同的结构可以在整个文件中重复多次,而始终遵循相同的结构。

“字幕列表” 下,我想确保“默认”:true ,而“ ID”:1 < / strong>和“跟踪”:0

否则,如果ID和Track等于其他任何值(例如,“ ID”:2和“ Track”:1或类似名称),则默认值应为false。

我认为这需要一个for循环,否则需要一个if循环。

以下是整个文件的示例:

[
  {
    "Job": {
      "Audio": {
        "AudioList": [
          {
            "Bitrate": 448,
            "DRC": 0.0,
            "Encoder": "ac3",
            "Gain": 0.0,
            "Mixdown": 7,
            "NormalizeMixLevel": false,
            "Samplerate": 0,
            "Track": 0,
            "DitherMethod": 0
          }
        ],
        "CopyMask": [
          "copy:aac",
          "copy:mp3"
        ],
        "FallbackEncoder": "ac3"
      },
      "Destination": {
        "ChapterList": [
          {
            "Name": "00:00:00.000"
          },
          {
            "Name": "00:03:43.723"
          },
          {
            "Name": "00:10:31.756"
          },
          {
            "Name": "00:13:25.847"
          },
          {
            "Name": "00:17:38.641"
          },
          {
            "Name": "00:19:35.841"
          },
          {
            "Name": "00:25:12.302"
          },
          {
            "Name": "00:28:01.305"
          },
          {
            "Name": "00:35:09.065"
          },
          {
            "Name": "00:43:07.084"
          },
          {
            "Name": "00:49:29.592"
          },
          {
            "Name": "00:52:14.214"
          },
          {
            "Name": "00:59:24.978"
          },
          {
            "Name": "01:02:53.728"
          },
          {
            "Name": "01:15:50.921"
          },
          {
            "Name": "01:21:28.801"
          },
          {
            "Name": "01:24:23.183"
          },
          {
            "Name": "01:31:45.875"
          },
          {
            "Name": "01:35:52.664"
          },
          {
            "Name": "01:44:06.282"
          }
        ],
        "ChapterMarkers": true,
        "AlignAVStart": false,
        "File": "C:\\Temp\\ExampleFixed.mkv",
        "Mp4Options": {
          "IpodAtom": false,
          "Mp4Optimize": false
        },
        "Mux": "mkv"
      },
      "Filters": {
        "FilterList": [
          {
            "ID": 4,
            "Settings": {
              "mode": "7"
            }
          },
          {
            "ID": 3,
            "Settings": {
              "block-height": "16",
              "block-thresh": "40",
              "block-width": "16",
              "filter-mode": "2",
              "mode": "3",
              "motion-thresh": "1",
              "spatial-metric": "2",
              "spatial-thresh": "1"
            }
          },
          {
            "ID": 11,
            "Settings": {
              "crop-bottom": "0",
              "crop-left": "0",
              "crop-right": "0",
              "crop-top": "0",
              "height": "404",
              "width": "720"
            }
          },
          {
            "ID": 6,
            "Settings": {
              "mode": "0"
            }
          }
        ]
      },
      "PAR": {
        "Num": 202,
        "Den": 195
      },
      "Metadata": {},
      "SequenceID": 0,
      "Source": {
        "Angle": 1,
        "Range": {
          "Type": "chapter",
          "Start": 1,
          "End": 20
        },
        "Title": 1,
        "Path": "C:\\Temp\\Example.mkv"
      },
      "Subtitle": {
        "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
        },
        "SubtitleList": [
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 0
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 1
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 3,
            "Offset": 0,
            "Track": 2
          }
        ]
      },
      "Video": {
        "Encoder": "x265",
        "Level": "auto",
        "TwoPass": false,
        "Turbo": false,
        "ColorMatrixCode": 0,
        "Options": "level=41",
        "Preset": "fast",
        "Profile": "auto",
        "Quality": 19.0,
        "QSV": {
          "Decode": false,
          "AsyncDepth": 0
        }
      }
    }
  },
  {
    "Job": {
      "Audio": {
        "AudioList": [
          {
            "Bitrate": 448,
            "DRC": 0.0,
            "Encoder": "ac3",
            "Gain": 0.0,
            "Mixdown": 7,
            "NormalizeMixLevel": false,
            "Samplerate": 0,
            "Track": 0,
            "DitherMethod": 0
          }
        ],
        "CopyMask": [
          "copy:aac",
          "copy:mp3"
        ],
        "FallbackEncoder": "ac3"
      },
      "Destination": {
        "ChapterList": [
          {
            "Name": "00:00:00.000"
          },
          {
            "Name": "00:03:43.723"
          },
          {
            "Name": "00:10:31.756"
          },
          {
            "Name": "00:13:25.847"
          },
          {
            "Name": "00:17:38.641"
          },
          {
            "Name": "00:19:35.841"
          },
          {
            "Name": "00:25:12.302"
          },
          {
            "Name": "00:28:01.305"
          },
          {
            "Name": "00:35:09.065"
          },
          {
            "Name": "00:43:07.084"
          },
          {
            "Name": "00:49:29.592"
          },
          {
            "Name": "00:52:14.214"
          },
          {
            "Name": "00:59:24.978"
          },
          {
            "Name": "01:02:53.728"
          },
          {
            "Name": "01:15:50.921"
          },
          {
            "Name": "01:21:28.801"
          },
          {
            "Name": "01:24:23.183"
          },
          {
            "Name": "01:31:45.875"
          },
          {
            "Name": "01:35:52.664"
          },
          {
            "Name": "01:44:06.282"
          }
        ],
        "ChapterMarkers": true,
        "AlignAVStart": false,
        "File": "C:\\Temp\\SecondExample.mkv",
        "Mp4Options": {
          "IpodAtom": false,
          "Mp4Optimize": false
        },
        "Mux": "mkv"
      },
      "Filters": {
        "FilterList": [
          {
            "ID": 4,
            "Settings": {
              "mode": "7"
            }
          },
          {
            "ID": 3,
            "Settings": {
              "block-height": "16",
              "block-thresh": "40",
              "block-width": "16",
              "filter-mode": "2",
              "mode": "3",
              "motion-thresh": "1",
              "spatial-metric": "2",
              "spatial-thresh": "1"
            }
          },
          {
            "ID": 11,
            "Settings": {
              "crop-bottom": "0",
              "crop-left": "0",
              "crop-right": "0",
              "crop-top": "0",
              "height": "404",
              "width": "720"
            }
          },
          {
            "ID": 6,
            "Settings": {
              "mode": "0"
            }
          }
        ]
      },
      "PAR": {
        "Num": 202,
        "Den": 195
      },
      "Metadata": {},
      "SequenceID": 0,
      "Source": {
        "Angle": 1,
        "Range": {
          "Type": "chapter",
          "Start": 1,
          "End": 20
        },
        "Title": 1,
        "Path": "C:\\Temp\\SecondExample.mkv"
      },
      "Subtitle": {
        "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
        },
        "SubtitleList": [
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 0
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 1
          },
          {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 3,
            "Offset": 0,
            "Track": 2
          }
        ]
      },
      "Video": {
        "Encoder": "x265",
        "Level": "auto",
        "TwoPass": false,
        "Turbo": false,
        "ColorMatrixCode": 0,
        "Options": "level=41",
        "Preset": "fast",
        "Profile": "auto",
        "Quality": 19.0,
        "QSV": {
          "Decode": false,
          "AsyncDepth": 0
        }
      }
    }
  }
]

“默认” 仅应等于“ true”,而“ ID”:1 “ Track”:0 ,否则应始终为“假”。

是否感谢有人可以帮助您为此构建.bat文件?

2 个答案:

答案 0 :(得分:1)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q56199380.txt"
SET "outfile=%destdir%\outfile.txt"
SET "hotsection="
CALL :clear$

(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 rem if line contains `SubtitleList` we've entered hot section
 ECHO "%%a"|FIND "SubtitleList">NUL
 IF NOT ERRORLEVEL 1 SET "hotsection=y"
 SET "saved="
 IF DEFINED hotsection (
  FOR /L %%r IN (100,1,999) DO IF NOT DEFINED saved IF NOT DEFINED $%%r SET "$%%r=%%a"&SET "saved=Y"
  rem if line contains `}]` or `}],` then end-of-hotsection
  SET "endhot="
  FOR /f "tokens=1delims= " %%w IN ("%%a") DO FOR %%x IN ("}]" "}],") DO IF "%%w"==%%x SET "endhot=Y"
  IF DEFINED endhot (
   rem end-of-hotsection
   rem check whether we have ID 1 and Track 0
   SET "id1="&SET "track0="
   FOR /f "tokens=1,*delims== " %%r IN ('SET $') DO (
    IF "%%s"==""ID": 1," SET "id1=Y" 
    IF "%%s"==""Track": 0" SET "track0=Y" 
   )
   rem found end-of-hotsection. now regurgitate saved lines and set `default` appropriately
   FOR /f "tokens=2delims==" %%r IN ('SET $') DO (
    echo "%%r"|FINDSTR /r /c:" *\"Default\":" >NUL
    IF ERRORLEVEL 1 (ECHO %%r) ELSE (
     FOR /f "tokens=1delims=:" %%s IN ("%%r") DO (
      IF defined track0 (IF DEFINED id1 (ECHO %%s: true,) ELSE (ECHO %%s: false,)) ELSE (ECHO %%s: false,)
     )
    )
    CALL :clear$
    SET "hotsection="
   )
  )
 ) ELSE (ECHO %%a)
)
)>"%outfile%"

GOTO :EOF

:clear$
:: remove variables starting $
FOR  /F "delims==" %%z In ('set $ 2^>Nul') DO SET "%%z="
GOTO :EOF

您需要根据自己的情况更改sourcedirdestdir的设置。

在测试中,我使用了一个名为q56199380.txt的文件,其中包含您的数据和一些虚拟数据。

产生定义为%outfile%的文件

usebackq选项是必需的,因为我选择在源文件名周围添加引号。

由于您的数据仅包含一个subtitlelist块,因此我扩展了数据以进行测试,并假设在subtitlelist中应该有多个subtitle,然后将每个分隔为}],而不是}]

总体上,使用标准的读取文本文件结构,将每一行依次分配给%%a

如果一行包含字符串subtitlelist,则我们输入的hot block可能会发生变化。这个hot block一直持续到找到}]}],

hot block之外的行由最后的echo %a重新定义。

该块中的内容存储在变量$???中,其中???是一个递增的3位数字。

当在一个块中检测到}]}],时,则endhot被设置为y(该方法克服了批处理缺少逻辑或)的特点检查存储在$ *中的"ID": 1,"Track": 0并设置适当的标志。

然后重新对$ *中保存的行进行反汇编,除了包含"Default":的行之前的任意数量的空格,其中行在:上进行拆分然后重建使用标志id1track0来控制分配给default的值。


发布更多数据后进行修订

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q56199380_2.txt"
SET "outfile=%destdir%\outfile.txt"
SET "hotsection="
CALL :clear$

(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 rem if line contains `SubtitleList` we've entered hot section
 ECHO "%%a"|FIND "SubtitleList">NUL
 IF NOT ERRORLEVEL 1 SET "hotsection=y"
 SET "saved="
 IF DEFINED hotsection (
  FOR /L %%r IN (100,1,999) DO IF NOT DEFINED saved IF NOT DEFINED $%%r SET "$%%r=%%a"&SET "saved=Y"
  rem if line contains `}]` or `}],` then end-of-hotsection
  SET "endhot="
  SET "endtrack="
  FOR /f "tokens=1delims= " %%w IN ("%%a") DO FOR %%x IN ("}]","},") DO IF "%%w"==%%x SET "endhot=Y"&IF "}]"==%%x SET "endtrack=Y"
  IF DEFINED endhot (
   rem end-of-hotsection
   rem check whether we have ID 1 and Track 0
   SET "id1="&SET "track0="
   FOR /f "tokens=1,*delims== " %%r IN ('SET $') DO (
    IF "%%s"==""ID": 1," SET "id1=Y" 
    IF "%%s"==""Track": 0" SET "track0=Y" 
   )
   rem found end-of-hotsection. now regurgitate saved lines and set `default` appropriately
   FOR /f "tokens=2delims==" %%r IN ('SET $') DO (
    echo "%%r"|FINDSTR /r /c:" *\"Default\":" >NUL
    IF ERRORLEVEL 1 (ECHO %%r) ELSE (
     FOR /f "tokens=1delims=:" %%s IN ("%%r") DO (
      IF defined track0 (IF DEFINED id1 (ECHO %%s: true,) ELSE (ECHO %%s: false,)) ELSE (ECHO %%s: false,)
     )
    )
    CALL :clear$
    IF DEFINED endtrack SET "hotsection="
   )
  )
 ) ELSE (ECHO %%a)
)
)>"%outfile%"

GOTO :EOF

:clear$
:: remove variables starting $
FOR  /F "delims==" %%z In ('set $ 2^>Nul') DO SET "%%z="
GOTO :EOF

几乎不需要更改。

  1. 我将filename1的设置更改为指向包含您修改后的数据的文件。

  2. 添加了一个额外的标记endtrack,以区分曲目描述(},)和路段结束(}]

  3. 连接到末尾的if s?现在使用},``}]进行检测,以检测是否找到了end-of-track

  4. 仅当结束时?如果检测到}],将清除hotsection标志以准备下一个subtitlelist

现在我意识到我所说的end[-of-]track实际上是end-of-subtitle。您将获得适当调整代码的所有乐趣。

答案 1 :(得分:0)

使用正则表达式解析和处理JSON似乎是个坏主意。但是我忍不住尝试用我的JREPL.BAT regular expression text processing utility解决方案。

jrepl "({[^}]*\qDefault\q\s*:\s*)[a-z]+([^}]*\qID\q\s*:\s*(\d+)[^}]*\qTrack\q\s*:\s*(\d+)[^}]*})"^
      "$txt=$1 + ($3=='1' && $4=='0' ? 'true' : 'false') + $2"^
      /p "\qSubtitleList\q:\s*\[[^\]]*\]"^
      /m /xseq /jq /f input.txt /o output.txt

我相信以上代码只要是可靠的:

  • 源文件是有效的JSON
  • SubtitleList数组对象中成员的顺序不变
  • SubtitleList数组对象成员中没有嵌套对象或数组
  • 可能还有一些我没想到的其他限制

以下是一些测试输入:

[
  {
    "Subtitle": {
      "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
      },
      "SubtitleList": [
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 0
        },
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 1
        },
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 2
        }
      ]
    }
  },
  {
    "Subtitle": {
      "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
      },
      "SubtitleList": [
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 0
        },
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 1
        },
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 2
        }
      ]
    }
  }
]

这是我的输出:

[
  {
    "Subtitle": {
      "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
      },
      "SubtitleList": [
        {
            "Burn": false,
            "Default": true,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 0
        },
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 1
        },
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 1,
            "Offset": 0,
            "Track": 2
        }
      ]
    }
  },
  {
    "Subtitle": {
      "Search": {
          "Burn": false,
          "Default": false,
          "Enable": false,
          "Forced": false
      },
      "SubtitleList": [
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 0
        },
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 1
        },
        {
            "Burn": false,
            "Default": false,
            "Forced": false,
            "ID": 2,
            "Offset": 0,
            "Track": 2
        }
      ]
    }
  }
]