Home > OS >  How can I edit the same two lines in multiple files in sequential order?
How can I edit the same two lines in multiple files in sequential order?

Time:04-04

I have a set of metadata where I need to edit the fields with a sequential number

  • Line 2 on each:
    "name": "#1"
    
  • Line 5 on each:
    "edition": 1,
    

I need to replace 1 on each line with sequential numbers in 580 files.

This is what I am trying to accomplish:

1.json

{
  "name": "#1",
  "description": "description",
  "image": "imagelink",
  "edition": 1,

2.json

{
  "name": "#2",
  "description": "description",
  "image": "imagelink",
  "edition": 2,

3.json

{
  "name": "#3",
  "description": "description",
  "image": "imagelink",
  "edition": 3,

etc

I am trying to modify the code here to work for my scenario:

https://unix.stackexchange.com/questions/508423/add-a-sequential-number-in-a-particular-line-for-multiple-files

I tried

perl -pi -e '$_ = sprintf("name": d %s",   $n, $_) if $. == 1; close ARGV if eof' *.json 

When I try this I dont get any change in any of the files.

CodePudding user response:

It's always easier and more robust to use an approach that actually understands JSON when working with the format. The following uses a couple of non-core modules, Path::Tiny and JSON::MaybeXS (If you're using homebrew for Mac package management, I don't see them available but you can install cpanminus and then do a cpanm Path::Tiny JSON::MaybeXS to install them.)

#!/usr/bin/env perl                                                                                                                                                                                                                               
use warnings;
use strict;
use feature qw/say/;
use Path::Tiny;
use JSON::MaybeXS;

my $json = JSON::MaybeXS->new->utf8->pretty;
# For each file matching the RE in the current directory
foreach my $file (path(".")->children(qr/^\d \.json$/)) {
  say "File $file";
  # Calculate the number based on the filename and update the JSON
  # object in-place
  $file->edit_raw(sub {
                    my $num = $file->basename(".json");
                    my $obj = $json->decode($_);
                    $obj->{name} = "#$num";
                    $obj->{edition} = $num   0;
                    $_ = $json->encode($obj);
                  });
}

CodePudding user response:

The following code snippets solved my problem:

perl -pi -e 's/#1/sprintf("#".   $n)/e' *.json(n)

The first addressed the issue of replacing #1 with #(sequential numbers)

perl -pi -e 's/: 1/sprintf(": ".  $n)/e' *.json(n)

The second addresses the issue of replacing : 1 (found in line 5) with :(sequential numbers)

  • Related