How to extract phone number and Pin from each text line

Viewed 185

Sample Text from the log file

2021/08/29 10:25:37 20210202GL1 Message Params [userid:user1] [timestamp:20210829] [from:TEST] [to:0214736848] [text:You requested for Pin reset. Your Customer ID: 0214736848 and PIN: 4581]
2021/08/27 00:03:18 20210202GL2 Message Params [userid:user1] [timestamp:20210827] [from:TEST] [to:0214736457] [text:You requested for Pin reset. Your Customer ID: 0214736457 and PIN: 6193]
2021/08/27 10:25:16 Thank you for joining our service; Your ID is 0214736849 and PIN is 5949

Other wording and formatting can change but ID and PIN don't change

Expected out put for each line

0214736848#4581
0214736457#6193
0214736849#5949

Below is what I have tried out using bash though am currently able to extract only the numeric values

while read p; do 

NUM='' 
counter=1;
text=$(echo "$p" | grep -o -E '[0-9]+')

for line in $text
do
if [ "$counter" -eq 1 ] #if is equal to 1
then
 NUM+="$line"  #concatenate string
 else
 NUM+="#$line"  #concatenate string
 fi
 let counter++  #Increment counter
done

printf "$NUM\n"
done < logfile.log

Current output though not the expected.

2021#08#29#00#03#18#20210202#2#1#20210826#0214736457#0214736457#6193
2021#08#27#10#25#37#20210202#1#1#20210825#0214736848#0214736848#4581
2021#08#27#10#25#16#0214736849#5949
5 Answers

Using sed capture groups you can do:

sed 's/.* Your Customer ID: \([0-9]*\) and PIN: \([0-9]*\).*/\1#\2/g' file.txt

Another variation using gawk and 2 capture groups, matching 1 or more digits per group:

awk '
match($0, /ID: ([0-9]+) and PIN: ([0-9]+)/, m) {
  print m[1]"#"m[2]
}
' file

Output

0214736848#4581
0214736457#6193

For the updated question, you could either match : or is if you want a more precise match, and the capture group values will be 2 and 4.

awk '
match($0, /ID(:| is) ([0-9]+) and PIN(:| is) ([0-9]+)/, m) {
  print m[2]"#"m[4]
}
' file

Output

0214736848#4581
0214736457#6193
0214736849#5949

With your shown samples please try following awk code, you could simple do it with using different field separators. Simple explanation would be, making Customer ID: OR and PIN: OR ]$ as field separators and then keeping them in mind printing only 2nd and 3rd fields along with # as per required output by OP.

awk -v FS='Customer ID: | and PIN: |]$' '{print $2"#"$3}' Input_file

With bash and a regex:

while IFS='] ' read -r line; do
  [[ "$line" =~ ID:\ ([^\ ]+).*PIN:\ ([^\ ]+)] ]]
  echo "${BASH_REMATCH[1]}#${BASH_REMATCH[2]}"
done <file

Output:

0214736848#4581
0214736457#6193

Given the updated input in your question then using any sed in any shell on every Unix box:

$ sed 's/.* ID[: ][^0-9]*\([0-9]*\).* PIN[: ][^0-9]*\([0-9]*\).*/\1#\2/' file
0214736848#4581
0214736457#6193
0214736849#5949

Original answer:

Using any awk in any shell on every Unix box:

$ awk -v OFS='#' '{print $18, $21+0}' file
0214736848#4581
0214736457#6193
Related