sizeur
sizeur

Reputation: 123

How to modify each line of a text?

I have a file which looks like this (it can have more than 2 lines):

$ cat /tmp/temp.txt 
;user1;1.1.1.1;DB1;SELECT;
;userX;2.2.2.2;DB4;SELECT;

And I want to change it like this:

user: user1 address: 1.1.1.1 db: DB1 right: SELECT
user: userX address: 2.2.2.2 db: DB4 right: SELECT

I think the simplest way to do it would be with the read function:

!/bin/bash

filename='/tmp/temp.txt'
while read ; do
  user=$(cut -d";" -f2 /tmp/temp.txt)
  address=$(cut -d";" -f3 /tmp/temp.txt)
  database=$(cut -d";" -f4 /tmp/temp.txt)
  right=$(cut -d";" -f5 /tmp/temp.txt)

 echo "user:$user address:$address database:$database right:$right"

done < $filename

The output of the script is:

user:user1
userX address:1.1.1.1
2.2.2.2 database:DB1
DB4 right: SELECT
SELECT
user:user1
userX address:1.1.1.1
2.2.2.2 database:DB1
DB4 right: SELECT
SELECT

I would like to have in my ouput the same number of lines as I have in the input file.

Upvotes: 2

Views: 2307

Answers (4)

Benjamin W.
Benjamin W.

Reputation: 52102

With sed, replacing semicolons one by one, from left to right:

$ sed 's/;/user: /;s/;/ address: /;s/;/ db: /;s/;/ right: /;s/;//' infile
user: user1 address: 1.1.1.1 db: DB1 right: SELECT
user: userX address: 2.2.2.2 db: DB4 right: SELECT

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 246744

If you want to stick with bash, you're on the right track, but you're doing too much work:

filename='/tmp/temp.txt'
while read ; do
  user=$(cut -d";" -f2 /tmp/temp.txt)
  address=$(cut -d";" -f3 /tmp/temp.txt)
  database=$(cut -d";" -f4 /tmp/temp.txt)
  right=$(cut -d";" -f5 /tmp/temp.txt)

 echo "user:$user address:$address database:$database right:$right"

done < $filename
  1. You're using while read; do ...; done < file kind of correctly, but then you're not using the data you read inside the loop. You have 4 cut commands inside the loop, so you're processing the whole file 4 times for each line in the file.

  2. read without any variable names stores the data in the default $REPLY variable. You could do

    filename='/tmp/temp.txt'
    while read ; do
      user=$(echo "$REPLY" | cut -d";" -f2)
      address=$(echo "$REPLY" | cut -d";" -f3)
      database=$(echo "$REPLY" | cut -d";" -f4)
      right=$(echo "$REPLY" | cut -d";" -f5)
      ...
    

    but that's still using external commands for something the shell can do natively.

  3. use the IFS variable to help you parse each line: you have semicolon-separated data, so you can do this:

    while IFS=";" read -r empty user address database right empty; do
        echo "user:$user address:$address database:$database right:$right"
    done < $filename
    

    Note the "empty" variable placeholders to hold the data before the first semicolon, and after the last one.

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133428

Could you please try following.

awk '
BEGIN{
  FS=";"
  OFS=": "
}
val{
  sub(/: $/,"",val)
  print val
  val=""
}
{
  $1="user"
  $2=$2 " address"
  $3=$3 " db"
  $4=$4" right"
  val=$0
}
END{
  if(val){
    sub(/: $/,"",val)
    print val
  }
}
'   Input_file

Upvotes: 0

Shawn
Shawn

Reputation: 52336

Just use awk:

$ awk -F ';' '{ print "user:", $2, "address:", $3, "db:", $4, "right:", $5 }' your_file

This splits each line of the file up on semicolons, and then prints out the desired columns in your desired output format.

Upvotes: 3

Related Questions