Разделить строку с разделителем слов на массив в bash - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть строка, подобная приведенной ниже:

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

хотел извлечь, как показано ниже, в массив

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 

Я пыталсяиспользуя IFS разделитель, но не удалось.Пожалуйста, кто-нибудь, помогите мне в этом

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Создайте свой массив с помощью GNU sed:

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

См .: FAQ по регулярным выражениям переполнения стека

1 голос
/ 24 сентября 2019

Это выполнимо, да.Если вы не возражаете поменять местами порядок массива, самый простой подход будет выглядеть примерно так:

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

... который выдает в качестве вывода (с разрывами строки, добавленными для удобства чтения):

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 "
)'

Если, напротив, вы хотите съесть штраф за производительность, чтобы сохранить исходный порядок, измените results+=( "${BASH_REMATCH[2]}" ) на results=( "${BASH_REMATCH[2]}" "${results[@]}" ).


То, что мы здесь делаем, соответствует последовательности иззадний ход вперед (поскольку bash не имеет не жадных регулярных выражений, первое .* соответствует всему * последнему dn:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...