[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 215
  • Last Modified:

Read and write to a file

I have a file I need to read and write to. The file is pound (#) delimited and it contains a list of filenames and 5 sets of numbers, ie


I need to do a few things:

Open this file and check is a previously set variable $input_file is any of the first field,
If  true check is another previously set variable, $figure is equal to any of the 5 sets of numbers.
If true print out a statement $figure is equal to previous figure

If not true pop off the first figure and write the new number to the end of the line.

For example

If the input file was Tom and the figure was 121,234, just a print out statement $figure is equal to previous figure


For example if the input file was John  and the figure was $677,061,  the new line for John would be
1 Solution
my $dbfile="/temp_ee/dbfile.txt";

my $input_file="John";
my $figure='$677,061';

my @data;
my $found;

#Read data
open(IN, "$dbfile") or die "could not open input file: $!\n";
while(<IN>) {
      push @data, [split /#/];
      next unless $data[-1]->[0] eq $input_file;
      for(my $i=1; $i<=$#{$data[-1]}; $i++) {
            if($data[-1]->[$i] eq $figure) {
                  print "$figure is equal to previous figure\n";

unless(defined($found)) {
      die "input_file '$input_file' not found\n";

#remove first number
print "Updating $input_file with $figure\n";
splice(@{$data[$found]}, 1, 1);
push @{$data[$found]}, $figure;

open(OUT, ">$dbfile") or die "Could not open output file: $!\n";
foreach (@data) {
      print OUT join("#", @{$_}) . "\n";
I'm a little confused about what you're trying to do -- you say you only have one pound delimited file to read, but then speak of "If the input file was Tom..." and "...if the input file was John...".  See if this is close:

#!/usr/bin/perl -w
use strict;

my (%data, @order, $match);

#my $figure = '$121,234';
#my $person = 'Tom';

my $figure = '$677,061';
my $person = 'John';

open (IN, "org_file.txt") or die;
while (<IN>) {
    my @line = split /#/;
    chomp (@line);
    push @order, $line[0];
    $data{$line[0]} = [@line[1 .. $#line]];

if (exists $data{$person}) {
    for (@{$data{$person}}) {
        if ($_ eq $figure) {
        $match = $figure;
    if ($match) {
        print "$person already has $match\n";
    } else {
        $data{$person}[-1] = "$figure";

open (OUT, ">new_file.txt") or die;

for (@order) {
    print OUT "$_#", join ("#", @{$data{$_}}), "\n";

You need to give it the person you want and the figure you're looking to match.  If, for example, you feed it:

my $figure = '$121,234';
my $person = 'Tom';

It prints out "Tom already has $121,234", and org_file.txt and new_file.txt are identical.  If instead you feed it:

my $figure = '$677,061';
my $person = 'John';

It doesn't print out anything, but new_file.txt becomes:


while org_file.txt remains:


Is this close?

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now