0

I am looking for a way to replace line 5 and line 7 in many documents inside of a directory. Line 5's offset and line 7's value are different for each of these documents, however, I need them to always be set to 0. This means line 5 should look like "color_stream_offset": 0," in all the documents and line 7 should look like "flags": 0," inside all of the documents.

I've attempted usage at SED, Notepad++ and none of them seem to be helpful. Each one of these documents has differences so I cannot just copy the file.

This is one of the many documents that needs replacing:

{
    "data": {
        "mesh": {
            "color_stream_count": 0,
            "color_stream_offset": 105920,
            "cull_distance": 1.0000000150474662e+30,
            "flags": 136,
            "lightmap_motifs": [
                0,
                0,
                0,
                0
            ],
            "lightmap_names": [],
            "lightmap_offsets": [
                0,
                0,
                0,
                0
            ],
            "mesh_name": "gomcbldf_00",
            "mesh_offset": 18172,
            "py/object": "lib.init_classes.Mesh",
            "tint": {
                "dimensions": 3,
                "py/object": "lib.ma_util.Vector",
                "x": 1.0,
                "y": 1.0,
                "z": 1.0
            }
        },
        "offset": 989012
    },
    "py/object": "lib.init_classes.ShapeData",
    "shape_type": "FWORLD_SHAPETYPE_MESH"
}
phuclv
  • 30,396
  • 15
  • 136
  • 260
VPG
  • 1

3 Answers3

2

I post following solution as a pragmatic one. To simplify it you can do it in two steps. You be warned - please make a backup copy of all files first.

I assume your files e.g file-1.txt and file-2.txtall have the extension *.txt and reside in folder e.g. D:\_working:

  • First open one of the files in your working directory by Notepad++
  • Ctrl+Shift+F
  • Go to the Find in Files tab
  • Find what:(.+)("color_stream_offset": )([0-9]{6}\,)
  • Replace with:\1\20,
  • Filters: *.txt
  • Directory: e.g. D:\_working
  • Check Match case
  • Search mode: Regular expression
  • Click on Replace in Files
  • Click on OK when you're really sure.

As a second step edit the Find What string to: (.+)("flags": )([0-9]{3}\,) and click on Replace in Files.

Please note the spaces in the Regex search string and change e.g. the digit {6} in the search string if you have different length here.

help-info.de
  • 2,159
1

This can be done in a single step:

  • Ctrl+Shift+F
  • Find what: (?:"color_stream_offset":|"flags":)\h*\K\d+
  • Replace with: 0
  • Filters: Whatever you want
  • Directory: Path\where\your\files\are
  • CHECK Regular expression
  • Replace in Files

Explanation:

(?:                           # non capture group
    "color_stream_offset":      # literally
  |                           # OR
    "flags":                    # literally
)                             # end group
\h*                 # 0 or more horizontal spaces
\K                  # forget all we've seen until this position
\d+                 # 1 or more digits

Screenshot:

enter image description here

Toto
  • 19,304
0

Generally you shouldn't use text replacement tools to update a structured text file like yaml, json or xml. You should use a dedicated tool instead. In Windows, PowerShell has built-in support for xml, json and many other formats so you can run this in PowerShell to replace the value in all json files in the current folder

Get-ChildItem *.json | ForEach-Object { 
    $d = Get-Content -Raw $_ | ConvertFrom-Json
    $d.data.mesh.color_stream_offset = 0
    $d.data.mesh.flags = 0
    ConvertTo-Json $d -Depth 10 >$_
}

Doing a simple search and replace in this case will fail if there's another line containing the same key-value pair, or in more complex cases may fail when a literal string matches the search string, or when the input array/dictionary lies in multiple lines for example. This method will always work if the structure is intact, and if the file is broken then it'll report immediately

For more information read


But if you really want to do textual operations then it's also easy to automate text replacement like this

Get-ChildItem *.json | ForEach-Object {
    (Get-Content -Raw $_) -replace `
        '("color_stream_offset"|"flags")\s*:\s*[0-9]+,', '$1: 0,' | Set-Content $_
}

There are a lot more other replacement methods in PowerShell that you can find in

phuclv
  • 30,396
  • 15
  • 136
  • 260