Изменить повторяющееся слово / текст в текстовом файле на основе соответствующего текста / параметра (ов) - PullRequest
0 голосов
/ 18 мая 2019

У меня есть текстовый файл, содержащий:

[{
      "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
        }]
    }
}]

Однако эту же структуру можно повторять несколько раз по всему файлу, всегда следуя одной и той же структуре.

Под "SubtitleList" , я хочу убедиться, что всегда "По умолчанию": true , тогда как "ID": 1 и "Track": 0 .

Иначе Если ID и Track совпадают с чем-либо еще (например," ID ": 2 и" Track ": 1 или что-то подобное), то по умолчанию должно быть false.

Я думаю, что для этого нужен цикл for или if if else.

Вот пример всего файла:

[
  {
    "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 , в противном случае оно всегда должно быть "false".

Спасибо, если кто-нибудь может помочь с тем, как структурировать файл .bat для этого?

Ответы [ 2 ]

1 голос
/ 19 мая 2019
@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

Вам необходимо изменить настройки sourcedir и destdir в соответствии с вашими обстоятельствами.

Я использовал файл с именем q56199380.txt, содержащий ваши данные и некоторые фиктивные данные для моего тестирования.

Создает файл, определенный как% outfile%

Параметр usebackq требуется только потому, что я решил добавить кавычки вокруг имени исходного файла.

Поскольку ваши данные содержали только один блок subtitlelist, я расширил данные для тестирования и предположил, что если в subtitle будет несколько subtitlelist с, то каждый будет разделен }], вместо }].

В целом используется стандартная структура чтения текстовых файлов, присваивая каждой строке по очереди %%a.

Если строка содержит строку subtitlelist, то мы вводим hot block, который может быть изменен. Это hot block сохраняется до тех пор, пока }] или }], не будет найдено.

Линии, находящиеся за пределами hot block, срываются в финал echo %a.

Те, которые находятся внутри блока, хранятся в переменной $???, где ??? - это возрастающее трехзначное число.

Когда в блоке обнаруживается }] или }],, тогда endhot устанавливается на y (методология устраняет отсутствие логического ИЛИ в пакете), и строки, хранящиеся в $ *, проверяются на "ID": 1, или "Track": 0 и соответствующие флаги установлены.

Затем сохраненные строки в $ * срыгиваются, за исключением строки, содержащей "Default":, перед которой стоит любое количество пробелов, где эта строка разбивается на : и затем восстанавливается с использованием флагов id1 и track0 для управления значением, присвоенным 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. Вы получаете удовольствие от правильной настройки кода.

0 голосов
/ 20 мая 2019

Парсинг и манипулирование JSON с помощью регулярных выражений кажется плохой идеей. Но я не смог устоять перед попыткой решения с помощью моей утилиты обработки текста с регулярными выражениями JREPL.BAT .

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
        }
      ]
    }
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...