0

Following Details are on a file called repo.

Date:   2010/10/19 19:05:06

Description:
        Created by rolandb.

Type:   local

I want to get the extract the details separately from a shell script. I have the following code

#!/bin/bash

        Date=`awk -v s="Date" 'index($0, s) == 1' repo`
        Description=`awk -v s="Description" 'index($0, s) == 1' repo`
        Type=`awk -v s="Type" 'index($0, s) == 1' repo`
        
        echo $Date 
        echo $Description
        echo $Type

It does not capture the line in description, as it is in the next line, The output is like :

Date: 2010/10/19 19:05:06
Description:

Type: local

How can i capture the line under the Description: from the shell script ?

  • 1
    Please add your desired output (no description) for that sample input to your question (no comment). – Cyrus Sep 26 '20 at 09:53
  • You shouldn't use 3 awk commands to capture 3 lines from the same file. You should also avoid backticks. Also `-v s="Date" 'index($0,s)==1'` is the same as `'/^Date/'` while I doubt that you want to save into a bash variable the whole string, but maybe only the date? Also avoid to use variables like Date or Type, that they could match reserved words in any programming environment. – thanasisp Sep 26 '20 at 09:59
  • For example, you may want to save the date in a bash variable, d="2010/10/19 19:05:06", the description like description="Created by rolandb." etc. This sounds reasonable, as you could after treat them as bash variables. Now saving the whole line into a variable, for almost all lines in file, does not really help, as you will have to parse these lines again to extract meaningful variables. – thanasisp Sep 26 '20 at 10:11

3 Answers3

1

Multiple little Awk scripts on the same file are a strong indication that you should be writing a bigger Awk script instead.

awk '$1 == "Date:" { date = $2 " " $3; next }
    $1 == "Description:" { fetch_next = 1; next }
    fetch_next { desc = $0; fetch_next = 0; next }
    $1 == "Type:" {
        print "Date:", date;
        print "Description:", desc;
        print "Type:", $1 }' repo

This contains multiple assumptions about the organization of your input file. If the file could contain multiple such records and you want to parse them all, that should be easy enough. If the Type field isn't always the last line in a record, that requires some changes in the logic. Both of these are common problems; it should not be hard to find existing questions about how to solve them, on this site and others.

There's alse a getline command which specifically fetches the next line; but I find that the above pattern (one or more variables to keep track of your state) is more broadly useful.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
tripleee
  • 175,061
  • 34
  • 275
  • 318
1

With bash:

#!/bin/bash

while read -r a b; do
  [[ "$a" == "Date:" ]] && echo "$a $b"
  [[ "$a" == "Description:" ]] && read -r b && echo "$a $b"
  [[ "$a" == "Type:" ]] && echo "$a $b"
done < repo

Output:

Date: 2010/10/19 19:05:06
Description: Created by rolandb.
Type: local
Cyrus
  • 84,225
  • 14
  • 89
  • 153
1

Your question is not completely clear, but the following should bring your description on a single line.

cat repo | paste -d' '  - - | awk '$1=$1'

If you want a shorter version, you can directly feed the file to paste command :

paste -d' ' - - < repo | awk '$1=$1'

This generates output like:

Date: 2010/10/19 19:05:06
Description: Created by rolandb.
Type: local

What is happening?

  1. paste -d' ' - - merges two consecutive lines into a single line.
  2. awk '$1=$1' removes unnecessary white spaces.
Amit Singh
  • 2,875
  • 14
  • 30