this post was submitted on 26 Aug 2023
30 points (100.0% liked)

Linux

48072 readers
1 users here now

From Wikipedia, the free encyclopedia

Linux is a family of open source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991 by Linus Torvalds. Linux is typically packaged in a Linux distribution (or distro for short).

Distributions include the Linux kernel and supporting system software and libraries, many of which are provided by the GNU Project. Many Linux distributions use the word "Linux" in their name, but the Free Software Foundation uses the name GNU/Linux to emphasize the importance of GNU software, causing some controversy.

Rules

Related Communities

Community icon by Alpár-Etele Méder, licensed under CC BY 3.0

founded 6 years ago
MODERATORS
 

I'm updating foundry to a version 11 and it broke an ass ton of my assets cause they're all "verified version 10"

So all I have to do is change that number, they're just maps so no need to update anything else, but I have like 400+ files to convert all in individual folders.

Please tell me there's an easy way to do this. (I'm on Linux obviously)

all 22 comments
sorted by: hot top controversial new old
[–] Kangie@lemmy.srcfiles.zip 30 points 2 years ago* (last edited 2 years ago) (2 children)
for file in $(find . -type f -iname '*.json'); do
  sed -i 's/"verified":"10"/"verified":"11"/' $file;
done
[–] duncesplayed@lemmy.one 24 points 2 years ago (2 children)

Find can actually do the sed itself if you don't want to use a subshell and a shell loop.

find . -type f -iname '*.json' -exec sed -i 's/"verified":"10"/"verified":"11"/' '{}' ';'
[–] wewbull@feddit.uk 7 points 2 years ago (1 children)

-print0 | xargs -0 sed -i to get a single sed process working across multiple files.

Add a -P 8 to xargs to get 8 parallel processes.

[–] csolisr@communities.azkware.net 4 points 2 years ago

Today I learned that xargs supports parallelization natively! That's gonna make some of my scripts much simpler

[–] brain_in_a_jar@kbin.social 7 points 2 years ago

Change the ';' to a '+' for even more efficiency (no need to fork+exec a sed process per file, sed can take multiple files)

[–] vipaal@aussie.zone 7 points 2 years ago

+1

And

In the off chance the files are not under git or some other VCS, might be a good idea to add the -b option to backup

[–] American_Jesus@lemm.ee 24 points 2 years ago (2 children)

With sed or awk, without a sample is hard to give a proper example.

sed -i 's/old/new/g' *.json 
[–] d3Xt3r@lemmy.nz 15 points 2 years ago

That rhymes!

With sed or awk, without a sample
is hard to give, a proper example

[–] MrSnowy@lemmy.ml 5 points 2 years ago* (last edited 2 years ago)

Name checks out, this is the way

Our sedvior!

[–] blashork@hexbear.net 11 points 2 years ago (2 children)

I also agree sed and some regex is your best bet

I recommend formatting the regex with regex101.com, I'm down to help you if you post some examples

Additionally there is a cli tool, I think jq or something like that, for processing json on the command line

I have foundry too, let me see if I can find the files that need to be updated

[–] Ithorian@hexbear.net 2 points 2 years ago* (last edited 2 years ago) (1 children)

Here's the GitHub link to one of the batches of files I'm working with.

This line ,,"compatibility":{"minimum":"9","verified":"10"}," needs to say" 11" in all the files

[–] blashork@hexbear.net 5 points 2 years ago* (last edited 2 years ago) (4 children)

I have made a python script and ran it on a clone of your git repo to confirm it works, simply run it at the root directory of wherever the files are, it will walk through and find module.json and do the replace.

#!/usr/bin/env python3

import re
import os

import fileinput

pattern = re.compile(r'(?P\.+)\"compatibility\":{\"minimum\":\"(?P\\d+)\",\"verified\":\"(?P\\d+)\"},(?P\.+)')

def make11(match):
    if match.groupdict().get('min', None) and match.groupdict().get('ver', None):
        return f"{match.groupdict()['pre']}\"compatibility\":{{\"minimum\":\"11\",\"verified\":\"11\"}},{match.groupdict()['post']}"

for root, dirs, files in os.walk("."):
    for file in files:
        if file == "module.json":
            for line in fileinput.input(f"{root}/{file}", inplace=True):
                print(re.sub(pattern, make11, line))

edit: lemmy is fucking with the formatting and removing the fucking regex group names, which will bork it. I've tried fixing it, dm me if you want me to send a downloadable link to the script

[–] Kangie@lemmy.srcfiles.zip 6 points 2 years ago

Neat script; just a touch overkill IMO compared to just using sed and bash!

Changing the minimum may be undesirable - I think it's only the latter value that needs to go from 10 -> 11.

[–] umami_wasbi@lemmy.ml 6 points 2 years ago

If using Python, why not just use JSON module? Simpler and easier maintain without all those regex.

Still +1, on sed if one is on Linux.

[–] Ithorian@hexbear.net 1 points 2 years ago

Holy shit that's awesome! Thanks

[–] SpaceCadet@feddit.nl 1 points 2 years ago* (last edited 2 years ago)

I also agree sed and some regex is your best bet

Nah, regexes are okay if you really have no other choice, but they're a bit of a hamfisted tool. For a json file, which is a neatly structured format, I would always try to do it with jq first.

[–] dreugeworst@lemmy.ml 11 points 2 years ago* (last edited 2 years ago)

You could use jq, which will work no matter how the json is formatted.

Without trying it out, something like the following might work:

jq '.path.to.key.to.change |= 11' file.json > file.json.tmp && mv file.json.tmp file.json

[–] thurstylark@lemm.ee 7 points 2 years ago

sed or awk might get you there, but something like jq which is meant for json might be a bit more ideal depending on your use-case.

[–] TheDeadCell@lemmy.sdf.org 4 points 2 years ago* (last edited 2 years ago) (1 children)

Since I don't know the structure of your files, I can't help entirely, but I would use find/locate to get a list of file paths, then use a script to take that list and use sed for the replacement, like this:

#!/bin/bash
for i in ListOfFilePaths.txt
do
  sed -i "s/oldtext/newtext/g" $i
done

Please copy the entire line for oldtext and newtext to avoid accidental replacements.

Also, I am very new to scripting, and this likely has multiple problems with it. I am just throwing out ideas.

[–] TheDeadCell@lemmy.sdf.org 4 points 2 years ago* (last edited 2 years ago) (1 children)

Looked at your github. I would do this in a script:

#!/bin/bash
find /base/path/of/files -type f -name "module.json" > ListOfFilePaths.txt

for i in ListOfFilePaths.txt
do
  sed -i "s/oldtext/newtext/g" $i
done

Once again, probably not the most efficient way to do it, but it might work.

[–] Ithorian@hexbear.net 3 points 2 years ago

Thanks I'll give that a try!