3

I have a large document with a similar structure:

Data800,
Data900,
Data1000,
]
}

How would I go about removing the last character from the 3rd to last line (in this case, where the comma is positioned next to Data1000). The output should look like this:

Data800,
Data900,
Data1000
]
}

It will always be the 3rd to last line in which needs the last character removed. Back-end is linux, and can use perl, bash, python, etc.

icehac
  • 147
  • 5
  • 14

5 Answers5

5

A simple solution using wc to count lines and sed to do the editing:

sed "$(( $(wc -l <file) - 2))s/,$//" file

That will output the edited file on stdout; you can edit inplace with sed -i.

rici
  • 234,347
  • 28
  • 237
  • 341
1

Perl's Tie::File module makes this trivial. It has the effect of tying an array to a disk file, so that any changes made to the array are reflected in the file

It would look like this (untested, as I'm posting from my tablet). The path to the input file is expected as a parameter on the command line. The line terminators are already removed from the strings that appear in the array, so a call to chop will remove the last character of the text

use strict;
use warnings;

use Tie::File;

tie my @file, 'Tie::File', shift or die $!;

chop $line[-3];

untie @file;
Borodin
  • 126,100
  • 9
  • 70
  • 144
-1

In python 2.* :

with open('/path/of/file', 'w+') as f:
    f.write(f.read().replace(',\n]', '\n]'))
M.javid
  • 6,387
  • 3
  • 41
  • 56
-1
with open('a.txt', "a+") as f:
    f.seek(-2, 2)                 # Jump to the second last byte.
    counter = 0
    while counter < 2:            # if found EOLS still not enough  
        if f.read(1) == "\n":     # Count EOLs
            counter += 1
        f.seek(-2, 1)             # jump back the read byte plus one more
    position = f.tell()           # save position
    last_three_lines = f.read()   # read last three lines
    f.seek(position, 0)           # jump back 
    f.truncate()                  # remove all the rest
    f.write(last_three_lines[1:]) # write back necessary stuff

Input:

AAAAAa
BBBBBb
CCCCCc
DDDDDd
EEEEEe
FFFFFf
GGGGGg

Output:

AAAAAa
BBBBBb
CCCCCc
DDDDDd
EEEEE
FFFFFf
GGGGGg
Sait
  • 19,045
  • 18
  • 72
  • 99
-1

The following removes commas followed by ] or by } (with optional whitespace between the two):

perl -0777pe's/,(?=\s*[\]}])//g'

Usage:

perl -0777pe's/,(?=\s*[\]}])//g' file.in >file.out   # Read from file
perl -0777pe's/,(?=\s*[\]}])//g' <file.in >file.out  # Read from STDIN
perl -i~ -0777pe's/,(?=\s*[\]}])//g' file            # In-place, with backup
perl -i -0777pe's/,(?=\s*[\]}])//g' file             # In-place, without backup
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Why the downvote? This is actually better than the accepted solution as it works not just at the end of the file, but everywhere else that needs to be fixed too. – ikegami Sep 14 '15 at 14:37