0

I have a string like below:

dn: uid=svc_ddvportal2ssh,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvportal2ssh svc_ddvportal2ssh krbpasswordexpiration: 20180607182429Z dn: uid=svc_ddvrundeckdeploy,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvrundeckdeploy svc_ddvrundeckdeploy krbpasswordexpiration: 20180607182430Z dn: uid=svc_bo2ansible_mon,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_bo2ansible_mon svc_bo2ansible_mon krbpasswordexpiration: 20990101200000Z

wanted to extract like below into array a

a[0] = dn: uid=svc_bo2icinga2ipa,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_bo2icinga2ipa svc_bo2icinga2ipa krbpasswordexpiration: 20180119194104Z
a[1] = dn: uid=svc_ddvrundeckdeploy,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvrundeckdeploy svc_ddvrundeckdeploy krbpasswordexpiration: 20180607182430Z
a[2] = uid=svc_bo2ansible_mon,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_bo2ansible_mon svc_bo2ansible_mon krbpasswordexpiration: 20990101200000Z 

I tried using IFS delimitor but not succeeded. Please someone help me into this

5
  • 1
    Which word, specifically, is the delimiter? Can you build shorter / easier to read sample data that makes the logic you want more obvious? (The minimal reproducible example rules don't just apply to code). Commented Sep 24, 2019 at 19:45
  • 1
    Why is there no dn: prefix on the a[2] value? Commented Sep 24, 2019 at 19:47
  • I have this suspicion that the line feeds aren't suppose to exist in the input string. Commented Sep 24, 2019 at 19:47
  • 1
    @JNevill, ...what line feeds? I don't see any in the question's text; it's just in single backticks to allow line wrapping to be done by the browser, so folks can actually read the input data without scrolling left-to-right. Commented Sep 24, 2019 at 19:48
  • a[2] also consists of dn element. Typo error. Commented Sep 24, 2019 at 20:19

2 Answers 2

2

Build your array with GNU sed:

mapfile -t a < <(sed -r 's/ .{14}Z /&\n/g' file)

See: The Stack Overflow Regular Expressions FAQ

Sign up to request clarification or add additional context in comments.

2 Comments

Maybe add a readarray or mapfile consuming the output of that sed command, since the OP wants to populate an array?
BTW, I'm curious which of us is right wrt. guessing the OP's intended delimiter -- you're stopping after Zs, I'm starting at a dn:. (BTW, maybe change it from .{14} to [[:digit:]]{14}?)
1

This is doable, yes. If you don't mind reversing the array's order, the easiest approach would look something like:

s='dn: uid=svc_ddvportal2ssh,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvportal2ssh svc_ddvportal2ssh krbpasswordexpiration: 20180607182429Z dn: uid=svc_ddvrundeckdeploy,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvrundeckdeploy svc_ddvrundeckdeploy krbpasswordexpiration: 20180607182430Z dn: uid=svc_bo2ansible_mon,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_bo2ansible_mon svc_bo2ansible_mon krbpasswordexpiration: 20990101200000Z'

while [[ $s =~ (.*)(dn: .*) ]]; do
  results+=( "${BASH_REMATCH[2]}" )
  s=${BASH_REMATCH[1]}
done
declare -p results # print the resulting array

...which emits as output (with line breaks added for readability):

declare -a results='(
  [0]="dn: uid=svc_bo2ansible_mon,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_bo2ansible_mon svc_bo2ansible_mon krbpasswordexpiration: 20990101200000Z"
  [1]="dn: uid=svc_ddvrundeckdeploy,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvrundeckdeploy svc_ddvrundeckdeploy krbpasswordexpiration: 20180607182430Z "
  [2]="dn: uid=svc_ddvportal2ssh,cn=users,cn=accounts,dc=tenant,dc=ycsdev,dc=io cn: svc_ddvportal2ssh svc_ddvportal2ssh krbpasswordexpiration: 20180607182429Z "
)'

If by contrast you're willing to eat a performance penalty to retain the original ordering, change results+=( "${BASH_REMATCH[2]}" ) to results=( "${BASH_REMATCH[2]}" "${results[@]}" ).


What we're doing here is matching the sequences from the back to the front (since bash doesn't have non-greedy regular expressions, the first .* matches everything to the last dn:).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.