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

Bash extract text from output

Hi all!

I have a very long output from a cat config.txt that is divided in sections.

Every section begins with:

FILESYSTEMNAME /var

or

FILESYSTEMNAME /media

or other file systems name

Then I have several rows including information about that filesystem, this is an example of a cat config.txt:

FILESYSTEMNAME /media
STUFF mystuff
SIZE 10gb
CREATIONDATE 12/4/2017
STUFF mystuff
STUFF mystuff
PARTITIONNUMBER 1

FILESYSTEMNAME /tmp
OTHERSTUFF myotherstuff
OTHERSTUFF myotherstuff
OTHERSTUFF myotherstuff
SIZE 30gb
STUFF mystuff
CREATIONDATE 10/5/2014
PARTITIONNUMBER 2


FILESYSTEMNAME /
SIZE 10gb
STUFF mystuff
CREATIONDATE 12/4/2017
OTHERSTUFF myotherstuff
PARTITIONNUMBER 1

As you can see the sections can contain a variable number of parameters, I've used STUFF and MYSTUFF to simulate that in the provided output.

I'd need to get, for example, the number of the month of CREATIONDATE for /tmp filesystem (using BASH), in this case the result would be 5.

What can I do to be get a reliable result?

Thanks for your help.
0
ltpitt
Asked:
ltpitt
  • 3
1 Solution
 
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
Sounds like a paragrep job.

Where paragrep means paragraph grep, so you're syntax will be something like...

paragrep /tmp config.txt | grep CREATIONDATE | other pipeline commands...

Open in new window


I'll look around + find a copy of a working paragrep for you, off one of my servers.

Some grep commands (like AIX) provide a grep option -p to do this + this flavor of grep is rare.
0
 
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
Here's a very crude version I slapped together at some point.

This will only work with small files, as it slurps (reads entire) file into memory.

If you're working with massive files, likely you can find far better code.

Using your provided config file, the following can be used...

net11 # paragrep /tmp config.txt | grep CREATIONDATE | fields 2
10/5/2014

Open in new window


Or use awk rather than fields.

#!/usr/bin/perl

use strict;
use warnings;

use File::Basename;

sub grep_via_file {

    $/ = undef; # slurp entire file, to allow multi-line greps
    my $pat = shift;

    foreach my $file (@ARGV) {

        open (IN,$file) || die "Unable to open($file): $!\n";
        my $data = <IN>;
        close(IN);

        print $1, "\n" if ($data =~ m#($pat)#sgio);

    }

}

sub grep_via_paragraph {

    die "usage: ", basename($0), " pat [files]\n" unless @ARGV;

    $/ = ""; # slurp file a paragraph at a time
    my $pat = shift @ARGV;

    $ARGV[0] = '-' unless @ARGV;

    my $sep = "";
    foreach my $file (@ARGV) {

        my $pf = 1;
        open (IN,$file) || die "Unable to open($file): $!\n";

        while (my $data = <IN>) {
           if ($data =~ /$pat/sgio) {
              print $sep, '==== ', $file,"\n" if $pf;
              $pf  = 0;
              $sep = "\n";
              print $data;
           }
        }

        close(IN);

     }

}

grep_via_paragraph;

Open in new window

0
 
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
Solution provided seems to be correct.

Poster has stopped posting.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

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