Reputation: 123
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
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
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
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.
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.
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
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
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