Tuesday, December 28, 2010

Bash - Concatenate with underscore in between


Input file:

$ cat file.txt
X 2 10
X 2 11
Y 5 12
Z 3 11
X 6 78

Required: For each of the lines of the above file, we are required to create sub directories of the following naming convention inside the directory outdir/.

i.e. for line
X 2 10
we need to create the sub directory:
outdir/b_config_X_2

The bash script I wrote:

$ cat createdir.sh
#!/bin/sh

while read line
do
eval $(echo "$line" | awk '{print "AID="$1";BID="$2";CID="$3}')
echo "$AID,$BID,$CID"
dir=b_config_$AID_$BID
mkdir -p outdir/$dir
done < file.txt

Executing it:

$ ./createdir.sh
X,2,10
X,2,11
Y,5,12
Z,3,11
X,6,78

Lets see what got created under outdir/

$ ls -l outdir/
total 16
drwxr-xr-x 2 root root 4096 Dec 28 04:54 b_config_2
drwxr-xr-x 2 root root 4096 Dec 28 04:54 b_config_3
drwxr-xr-x 2 root root 4096 Dec 28 04:54 b_config_5
drwxr-xr-x 2 root root 4096 Dec 28 04:54 b_config_6

To make it work, I did the following change in the above script:

dir=b_config_$AID\_$BID

So the modified script:

$ cat createdir.sh
#!/bin/sh

while read line
do
eval $(echo "$line" | awk '{print "AID="$1";BID="$2";CID="$3}')
echo "$AID,$BID,$CID"
dir=b_config_$AID\_$BID
mkdir -p outdir/$dir
done < file.txt

After execution, it created the correct sub directories:

$ ls -l outdir/
total 16
drwxr-xr-x 2 root root 4096 Dec 28 04:56 b_config_X_2
drwxr-xr-x 2 root root 4096 Dec 28 04:56 b_config_X_6
drwxr-xr-x 2 root root 4096 Dec 28 04:56 b_config_Y_5
drwxr-xr-x 2 root root 4096 Dec 28 04:56 b_config_Z_3

The other alternative to concatenate values of two variables with underscore in between is:

dir=b_config_${AID}_${BID}

What is the use of the following Awk eval function ?

eval $(echo "$line" | awk '{print "AID="$1";BID="$2";CID="$3}')

is a replacement of:

AID=$(echo $line | awk '{print $1}')
BID=$(echo $line | awk '{print $2}')
CID=$(echo $line | awk '{print $3}')

or

AID=$(echo $line | cut -d " " -f1)
BID=$(echo $line | cut -d " " -f2)
CID=$(echo $line | cut -d " " -f3)

Related post:
- UNIX Bash script to copy required files
- UNIX Bash cat command space issue explained
- Bash Script while loop issue explained

4 comments:

Anand Subramanian said...

Hi Jadu,

I really like the way you used eval to assign values to AID, BID and CID. I was on the look out for a solution that would do the assignment.

I used a very slow method:
A=echo $str | awk '{print $1}'
B=echo $str | awk '{print $2}'
etc

You method of using eval is much better than the one I knew.

Because of your work I am a little better than before.

Unknown said...

@Anand, nice to hear this. Thanks.

Naveen said...

Really impressed with your scripting......From past 6 years am into Linux administration, now I need to do complex coding (Bash/Power shell) due to change of my profile , dont know how to achieve this. Thanks again for all your input.

Unknown said...

< file.txt input perl -pale '$_ = join"_", qw|outdir/b config|, @F[0,1]' | xargs -l -t mkdir -p

© Jadu Saikia www.UNIXCL.com