0

I am trying to create a text file with below content

user name is ${name}
and his mobile number is ${number}

I have 10 users and 10 mobile numbers as well. User names are saved in user.txt and the contact number is saved in contact.txt.

user.txt looks like below.

apple
cat
tom

contact.txt looks like below,

1234
3456
5678

my output should look like below.

user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

I want this output in single file. Could someone please help me with the shell and python script?

4 Answers 4

1

This can be done with standard shell builtins and common tools.

paste -d'|' user.txt contact.txt | while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done

Slight remix with a bashism that is often preferred for input redirection.

while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done < <(paste -d"|" user.txt contact.txt)

The entire output can be redirected to a file of your choice by adding > "somefilename.txt" to the last line of either command.

1

The paste command could be used to pair the lines of the two files so that we may read them easier:

paste user.txt contact.txt

This creates a tab-delimited data stream of two fields.

This is easily read and modified by e.g. awk:

awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'

This uses printf in awk to create a string that is outputted. The two fields read from the output of paste are read automatically into $1 and $2 and they are inserted into the output string where it says %s (a placeholder for the next string given as an argument to printf). The -F '\t' on the command line of awk sets the field delimiter to a tab character.

Putting these two together and testing it:

$ paste user.txt contact.txt | awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'
user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

Redirect this into a file using >somename at the end of the command.


A different way of doing this is to modify the output field separator (OFS) and the output record separator (ORS), and instead of using printf just modify the first and second field (the trailing 1 at the end causes the output of the modified line):

paste user.txt contact.txt |
awk -F '\t' -v OFS='\n' -v ORS='\n\n' '{ $1 = "user name is " $1; $2 = "and his mobile number is " $2 }; 1'
1

bash has the mapfile builtin command, that reads in a file into an array as one element per line. -t removes trailing newlines. You may then just loop over the arrays:

#!/bin/bash
mapfile -t user <user.txt
mapfile -t number <contact.txt
for (( i=0 ; i<${#user[@]} ; i++ )) ; do
  echo "user name is ${user[i]}"
  echo "and his mobile number is ${number[i]}"
  echo
done
3
  • Neat ... Could just do this to get i values: for i in ${!user[*]} ; do
    – bxm
    Jan 25, 2022 at 15:15
  • 1
    @bxm That would split the keys on whitespaces though, and do globbing. You probably meant "${!user[@]}". I'm also not sure if ordering is guaranteed to be the same.
    – Kusalananda
    Jan 25, 2022 at 16:28
  • The keys are purely numeric for a "normal" array, so I'm not sure that white space and globbing come into play...?
    – bxm
    Jan 25, 2022 at 20:17
0

With zsh:

users=( ${(f)"$(<users.txt)"} )
numbers=( ${(f)"$(<numbers.txt)"} )
printf 'user name is %s\nand their mobile is %s\n\n' ${users:^numbers}

${A:^B} and ${A:^^B} are two array-zipping operators. The difference between the two can be seen when the two arrays are not of the same length like in A=(a b c) B=(1 2 3 4 5) in which case ${A:^B} yields a 1 b 2 c 3 (discarding the excess from B) while ${A:^^B} yields a 1 b 2 c 3 a 4 b 5 (reusing A members to match against the excess in B.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .