Bəşdəki bir məhdudlaşdırıcıda simli necə bölünür?

Bir dəyişəndə ​​saxlanan bu simli var:

 IN="bla@some.com;john@home.com" 

İndi xətlərin ayırıcı ilə ayrılmasını istəyirəm ; mənim üçün belədir:

 ADDR1="bla@some.com" ADDR2="john@home.com" 

Mən mütləq ADDR1ADDR2 dəyişənlərinə ehtiyac ADDR2 . Onlar daha da yaxşı olan elementlərdir.


Aşağıdakı cavabların təkliflərindən sonra aşağıdakıları tamamladım:

 #!/usr/bin/env bash IN="bla@some.com;john@home.com" mails=$(echo $IN | tr ";" "\n") for addr in $mails do echo "> [$addr]" done 

Nəticə:

 > [bla@some.com] > [john@home.com] 

Internal_field_separator (IFS) 'ni təyin etməklə bağlı bir həll var idi ; . Bu cavabın nə olduğuna əmin deyiləm, IFS default olaraq necə sıfırladınız?

RE: IFS həllini IFS və çalışır, köhnə IFS saxlayır və bərpa edirəm:

 IN="bla@some.com;john@home.com" OIFS=$IFS IFS=';' mails2=$IN for x in $mails2 do echo "> [$x]" done IFS=$OIFS 

Yeri gəlmişkən, çalışdığım zaman

 mails2=($IN) 

$IN ətrafında brackets olmadan bir loop çap zaman ilk line var $IN bu işləyir.

1509
28 мая '09 в 5:03 2009-05-28 05:03 stefanB tərəfindən 28 May '09 saat 05:03 'da təyin olundu 2009-05-28 05:03
@ 34 cavab
  • 1
  • 2

Daxili sahəsi ayırıcı (IFS) dəyişənini təyin edə bilərsiniz və sonra onu bir sıra halına gətirmək üçün icazə verin. Bu bir əmrdə baş verərsə, IFS təyinatı bu mühitdə yalnız bir komanda ilə ( read qədər) baş verir. Daha sonra, girişin IFS dəyişəninin dəyərinə uyğun olaraq analiz edilərək, sonra biz keçid edə biləcəyik.

 IFS=';' read -ra ADDR <<< "$IN" for i in "${ADDR[@]}"; do # process "$i" done 

Ayrılmış elementlərdən bir sıra təhlil ediləcək ; bir dizəyə tıklayarak. İşlənən material yalnız $IN , hər dəfə bir xətt bir xarakterlə ayrılır ; :

  while IFS=';' read -ra ADDR; do for i in "${ADDR[@]}"; do # process "$i" done done <<< "$IN" 
923
28 мая '09 в 5:23 2009-05-28 05:23 Johannes Schaub - 28 May '09 saat 05:23 'da cavab verdi 2009-05-28 05:23

Baş kabuk skriptindən split ardıcıldan alındı:

 IN="bla@some.com;john@home.com" arrIN=(${IN//;/ }) 

Şərhlər:

Bu tikinti bütün hadisələri əvəz edir ';' (ilkin // qlobal dəyişdirmə deməkdir) ' ' (bir məkan) ilə ' ' IN simvolu ' ' içərisində, sonra da yer ayrılmış simli bir sıra (bu ətrafdakı parantezlər) olaraq şərh edir.

border=0

Buruq parantezlər içərisində istifadə edilən sintaksis hər bir xarakterin əvəz edilməsi ';' ' ' Simvolu parametrlərin genişləndirilməsi adlanır.

Bəzi səhvlər var:

  • Mənbə xəttində boşluqlar varsa, IFS- dən istifadə etməlisiniz :
    • IFS=':'; arrIN=($IN); unset IFS;
  • Mənbə xəttində boşluqlar varsa və məhdudlaşdırıcı yeni bir xəttdirsə, IFS'i aşağıdakılarla təyin edə bilərsiniz:
    • IFS=$'\n'; arrIN=($IN); unset IFS;
744
10 марта '11 в 12:00 2011-03-10 12:00 Cavab palindromu 10 Mart 11: 00-da verilir. 2011-03-10 12:00

Onları dərhal işləməyinizə zidd deyilsə, bunu etmək istəyirəm:

 for i in $(echo $IN | tr ";" "\n") do # process done 

Bir dizi başlatmaq üçün bu cür loopdan istifadə edə bilərsiniz, amma bunu etmək daha asan bir yoludur. Bu kömək edir.

207
28 мая '09 в 5:09 2009-05-28 05:09 Cavab Chris Lutz tərəfindən 28 May 'da 5:09' də verildi. 2009-05-28 05:09

Uyğun cavab

Bu məsələdə, BŞ-də bunu bir çox başqa yol var. Amma bash çox bənzərsiz xüsusiyyətlərə sahibdir, bəşisizm yaxşı işləyir, amma başqa bir işləməyəcək.

Xüsusilə, diziler, birləşmə serialları və jokerlər saf bashizmlərdir və digər qabıqlarda işləməyəcəkdir.

Mənim Debian GNU / Linux-da standart çöküntü adlanır, lakin ksh istifadə etmək istəyən bir çox insanı tanıyıram .

Nəhayət, çox kiçik bir vəziyyətdə, kabuk tərcüməçi ( ) ilə xüsusi bir vasitə var.

İstədiyiniz simli

Sözügedən məsələnin nümunəsi:

 IN="bla@some.com;john@home.com" 

Bu boşluqlarla faydalı ola biləcəyindən və boşluqlar bir alt proqramın nəticəsini dəyişə bildiyindən bu təxminən xəttdən istifadə etməyi üstün edirəm:

  IN="bla@some.com;john@home.com;Full Name <fulnam@other.org>" 

Başlı bir məhdudiyyətə əsaslanan bir simli (versiya> = 4.2)

Təmiz bir bash ilə diziler və IFS istifadə edə bilərsiniz:

 var="bla@some.com;john@home.com;Full Name <fulnam@other.org>" 

 oIFS="$IFS" IFS=";" declare -a fields=($var) IFS="$oIFS" unset oIFS 

 IFS=\; read -a fields <<<"$var" 

Bu sözdizimini son bashdə istifadə edərək, hazırda $IFS i cari seans üçün dəyişmir, ancaq mövcud əmr üçün:

 set | grep ^IFS= IFS=$' \t\n' 

İndi string var bölünür və bir sıra (ad fields ) saxlanılır:

 set | grep ^fields=\\\|^var= fields=([0]="bla@some.com" [1]="john@home.com" [2]="Full Name <fulnam@other.org>") var='bla@some.com;john@home.com;Full Name <fulnam@other.org>' 

Dəyişən məzmunu declare -p etməklə declare -p :

 declare -p var fields declare -- var="bla@some.com;john@home.com;Full Name <fulnam@other.org>" declare -a fields=([0]="bla@some.com" [1]="john@home.com" [2]="Full Name <fulnam@other.org>") 

read bir çöküşün ən sürətli yolu, çünki heç bir çəngəl və xarici resurslar yoxdur.

Oradan hər bir sahəni idarə etmək üçün bildiyiniz sözdizimdən istifadə edə bilərsiniz:

 for x in "${fields[@]}";do echo "> [$x]" done > [bla@some.com] > [john@home.com] > [Full Name <fulnam@other.org>] 

və ya hər bir sahəni emal etdikdən sonra buraxın (mən bu keçid anlayışını sevirəm):

 while [ "$fields" ] ;do echo "> [$fields]" fields=("${fields[@]:1}") done > [bla@some.com] > [john@home.com] > [Full Name <fulnam@other.org>] 

hətta bir sadə çap üçün (qısa sintaksis):

 printf "> [%s]\n" "${fields[@]}" > [bla@some.com] > [john@home.com] > [Full Name <fulnam@other.org>] 

Kabuğdakı bir məhdudlaşdırıcıya əsaslanan bir simli

Ancaq bir çox kabuklarda istifadə üçün uyğun bir şey yazarsanız, heç bir bachizm istifadə etməməlisiniz.

Bir dizəyin bir və ya sonuncu başlığına bir simli bölmək üçün bir çox kabuklarda istifadə olunan sintaksis var:

 ${var#*SubStr} # will drop begin of string up to first occur of `SubStr` ${var##*SubStr} # will drop begin of string up to last occur of `SubStr` ${var%SubStr*} # will drop part of string from last occur of `SubStr` to the end ${var%%SubStr*} # will drop part of string from first occur of `SubStr` to the end 

(Bunun olmaması cavabımı yayımlamaq üçün əsas səbəbdir;)

Score_Under tərəfindən göstərildiyi kimi:

#% ən qısa uyğunluq satırını silin və

##%% maksimum vaxtını silin.

Bu kiçik nümunə script, bash , , , altında işləyir və Mac OS bash-da test edilmişdir:

 var="bla@some.com;john@home.com;Full Name <fulnam@other.org>" while [ "$var" ] ;do iter=${var%%;*} echo "> [$iter]" [ "$var" = "$iter" ]  \ var='' || \ var="${var#*;}" done > [bla@some.com] > [john@home.com] > [Full Name <fulnam@other.org>] 

Uğurlar!

121
13 апр. cavab F. Hauri tərəfindən 13 apreldə verilir 2013-04-13 17:20 '13 at 17:20 2013-04-13 17:20

Bu yanaşma necədir:

 IN="bla@some.com;john@home.com" set -- "$IN" IFS=";"; declare -a Array=($*) echo "${Array[@]}" echo "${Array[0]}" echo "${Array[1]}" 

Mənbə

80
28 мая '09 в 13:31 2009-05-28 13:31 28 may '09 'da 1:31' də verilmiş cavab verici 2009-05-28 13:31

cut istinadən bir neçə cavab gördüm, lakin hamısı silindi. Heç kim bu barədə danışılan bir az qəribədir, çünki bu xüsusilə məhdudlaşdırılmış log fayllarının ayrılması üçün bu cür bir şey üçün ən faydalı əmrlərdən biri hesab edirəm.

Bu xüsusi nümunəni bir sıra halına gətirərkən bash script tr , yəqin daha səmərəli olur, ancaq müəyyən sahələri ortadan çıxarmaq istəyirsinizsə cut və daha məhsuldar istifadə edilə bilər.

Məsələn:

 $ echo "bla@some.com;john@home.com" | cut -d ";" -f 1 bla@some.com $ echo "bla@some.com;john@home.com" | cut -d ";" -f 2 john@home.com 

Əlbəttə ki, hər bir sahəni müstəqil şəkildə çəkmək üçün bir döngəyə qoyun və -f variantından istifadə edin.

Bu kimi xətləri olan ayrılmış bir günlük faylı varsa, daha faydalı olur:

 2015-04-27|12345|some action|an attribute|meta data 

cut bu faylda cat edə bilmək və daha çox emal üçün müəyyən bir sahəni seçmək üçün çox rahatdır.

74
27 апр. Apr 27-də DougW tərəfindən verilmiş cavab 2015-04-27 21:20 '15 at 21:20 2015-04-27 21:20

Mənim üçün çalışdı:

 string="1;2" echo $string | cut -d';' -f1 # output is 1 echo $string | cut -d';' -f2 # output is 2 
65
11 авг. Steven Lizarazo tərəfindən verilən cavab 11 avqust. 2016-08-11 23:45 '16 saat 11:45 'də 2016-08-11 23:45
 echo "bla@some.com;john@home.com" | sed -e 's/;/\n/g' bla@some.com john@home.com 
59
28 мая '09 в 5:12 2009-05-28 05:12 28 may, '09 'da 5:12' da loşarına cavab verdi 2009-05-28 05:12

Həm də işləyir:

 IN="bla@some.com;john@home.com" echo ADD1=`echo $IN | cut -d \; -f 1` echo ADD2=`echo $IN | cut -d \; -f 2` 

Ehtiyatlı olun, bu qərar həmişə doğru deyil. Yalnız "bla@some.com" ünvanını ötürürsə, ADD1 və ADD2 adını təyin edəcəkdir.

57
08 сент. Cavab Ashok tərəfindən verilir 08 Sep 2012-09-08 08:01 '12 at 8:01 am 2012-09-08 08:01

Hesab edirəm ki, AWK probleminizi həll etmək üçün ən yaxşı və effektiv komandadır. AWK demək olar ki, hər Linux dağıtımında default ilə Bash daxil edilir.

 echo "bla@some.com;john@home.com" | awk -F';' '{print $1,$2}' 

verəcək

 bla@some.com john@home.com 

Əlbəttə ki, hər bir elektron poçt ünvanını awk yazma sahəsində əsas götürərək saxlaya bilərsiniz.

32
14 янв. Cavab Tony 14 yanvar verilir . 2013-01-14 09:33 '13 at 9:33 2013-01-14 09:33

Darrona cavab verən başqa bir yanaşma, mən bunu necə edirəm:

 IN="bla@some.com;john@home.com" read ADDR1 ADDR2 <<<$(IFS=";"; echo $IN) 
25
05 июля '11 в 16:41 2011-07-05 16:41 cavab 05 iyul 'da saat 16: 41 -də ləqəblə verilmişdir 2011-07-05 16:41

Bash-da, dəyişən dəyişən xarakterli olsa da işləyəcək bulletproof bir şəkildə:

 IFS=';' read -d '' -ra array < <(printf '%s;\0' "$in") 

Görünüş:

 $ in=$'one;two three;*;there is\na newline\nin this field' $ IFS=';' read -d '' -ra array < <(printf '%s;\0' "$in") $ declare -p array declare -a array='([0]="one" [1]="two three" [2]="*" [3]="there is a newline in this field")' 

Bunun üçün hiylə qurmaq -d read seçimini (məhdudlaşdırıcıyı) boş bir məhdudlaşdırıcı ilə istifadə etməkdir, buna görə read o qidalanan hər şeyi oxumağa məcburdur. Və printf sayəsində sonsuz yeni bir xətt olmadan, dəyişənin məzmunu daxilində kök read . Qeyd edək ki, simvolun read keçirildiyini təmin etmək üçün printf də bir məhdudlaşdırıcı qoyduq. Onsuz read , potensial son boş sahələri kəsin:

 $ in='one;two;three;' # there an empty field $ IFS=';' read -d '' -ra array < <(printf '%s;\0' "$in") $ declare -p array declare -a array='([0]="one" [1]="two" [2]="three" [3]="")' 

qalan boş sahə saxlanılır.


Bash ≥4.4 üçün yeniləmə

Bəş 4.4-dən bəri, quraşdırılmış mapfile (aka readarray ) separatorı göstərmək üçün -d dəstəkləyir. Buna görə, başqa bir kanonik yol:

 mapfile -d ';' -t array < <(printf '%s;' "$in") 
23
26 июня '14 в 12:11 2014-06-26 12:11 Cavab gniourf_gniourf tərəfindən 26 iyun '14 'də saat 12:11' də verilir 2014-06-26 12:11

Bu hər yerdə işləməlidir:

 echo "luke;yoda;leila" | tr ";" "\n" 

(Başqa olduğunuz halda bu metodun dəyərinə diqqət yetirin və sadəcə, sadə və qısa bir hiylə lazımdırsa, akademik və "doğru" yol digər yazılarda göstərildiyi kimi IFS-dən istifadə etməkdir).

22
03 дек. Avt'W cavab 03 dekabr . 2017-12-03 03:40 '17, 3:40 'də 2017-12-03 03:40

Necə ki, bu bir liner haqqında, diziləri istifadə etmirsinizsə:

 IFS=';' read ADDR1 ADDR2 <<<$IN 
18
13 сент. Cavab Darron tərəfindən verilir Sep 13 2010-09-13 23:10 '10 'da saat 11:10' da 2010-09-13 23:10

IFS qəbulu olmadan

Yalnız bir kolonunuz varsa, bunu edə bilərsiniz:

 a="foo:bar" b=${a%:*} c=${a##*:} 

alacaqsınız:

 b = foo c = bar 
16
01 авг. Cavab Emilien Brigand 01 aug tərəfindən verilir . 2016-08-01 16:15 '16 16:15 'da 2016-08-01 16:15

Burada təmiz bir 3-liner var:

 in="foo@bar;bizz@buzz;fizz@buzz;buzz@woof" IFS=';' list=($in) for item in "${list[@]}"; do echo $item; done 

IFS məhdudlaşdırıcıya əsaslanan sözləri məhdudlaşdırır və () bir sıra yaratmaq üçün istifadə olunur. Sonra [@] hər bir maddənin ayrı bir söz olaraq qaytarılması üçün istifadə olunur.

Bundan sonra hər hansı bir $IFS , məsələn, $IFS i bərpa etmək lazımdır. unset IFS .

14
11 сент. cavab verildi . 2015-09-11 23:54 '15 at 11:54 pm 2015-09-11 23:54

Sadə və aydın bir yol var:

 echo "add:sfff" | xargs -d: -i echo {} 

Amma gnu xargs istifadə etməliyəm, BSD xargs dəstəkləyə bilməz -d delim. Mənim kimi apple mac istifadə edirsinizsə. Gnu xargs yükləyə bilərsiniz:

 brew install findutils 

sonra

 echo "add:sfff" | gxargs -d: -i echo {} 
7
16 сент. Çərşənbə günü Viktor Choy tərəfindən cavab verildi 2015-09-16 06:34 '15 'də 6:34' de 2015-09-16 06:34

Aşağıdakı Bash / zsh funksiyası ilk arqumentini ikinci arqument tərəfindən göstərilən məhdudlaşdırıcıya ayırır:

 split() { local string="$1" local delimiter="$2" if [ -n "$string" ]; then local part while read -d "$delimiter" part; do echo $part done <<< "$string" echo $part fi } 

Məsələn, əmr

 $ split 'a;b;c' ';' 

verir

 a b c 

Bu çıxış, məsələn, digər əmrlərə keçə bilər. Məsələn:

 $ split 'a;b;c' ';' | cat -n 1 a 2 b 3 c 

Alınan digər həllər ilə müqayisədə aşağıdakı üstünlüklərə malikdir:

  • IFS ləğv edilmir: hətta yerli dəyişənlərin dinamik əhatəsinə görə, bir dövrdə IFS ə üstünlük verən yeni dəyər döngünün içərisində yerinə yetirilən funksiya çağırışlarına axır.

  • Sütunlar istifadə edilmir: oxu istifadə edərək bir dizəyə bir simli read Bash-in bayrağı və z-də -a tələb olunur.

İstənilən halda funksiya skriptə aşağıdakı şəkildə yerləşdirilə bilər:

 #!/usr/bin/env bash split() { # ... } split "$@" 
4
24 мая '17 в 11:42 2017-05-24 11:42 Cavab Halle Knast tərəfindən 24 May '17 'də 11:42 2017-05-24 11:42' də verilir

Bunu etmək ən asan yoludur.

 spo='one;two;three' OIFS=$IFS IFS=';' spo_array=($spo) IFS=$OIFS echo ${spo_array[*]} 
4
25 сент. Cavab Prospero 25-də verilir . 2011-09-25 04:09 '11 at 4:09 2011-09-25 04:09
 IN="bla@some.com;john@home.com" IFS=';' read -a IN_arr <<< "${IN}" for entry in "${IN_arr[@]}" do echo $entry done 

Çıxın

 bla@some.com john@home.com 

Sistem: Ubuntu 04.04.1

3
25 окт. Cavab rashok Oct 25. 2016-10-25 15:41 '16 at 3:41 pm 2016-10-25 15:41

bir çox hal üçün awk müraciət edə bilərsiniz

 echo "bla@some.com;john@home.com"|awk -F';' '{printf "%s\n%s\n", $1, $2}' 

Bundan da istifadə edə bilərsiniz

 echo "bla@some.com;john@home.com"|awk -F';' '{print $1,$2}' OFS="\n" 
3
20 янв. cavab kiaihanhungry 20 yanvar. 2018-01-20 18:54 '18 at 18:54 2018-01-20 18:54

Heç bir yer yoxdursa, niyə bu deyil?

 IN="bla@some.com;john@home.com" arr=(`echo $IN | tr ';' ' '`) echo ${arr[0]} echo ${arr[1]} 
2
24 апр. cavabı 24 apr verilir . 2013-04-24 16:13 '13 at 16:13 2013-04-24 16:13

Buradakı bir neçə maraqlı cavab var (səhv bir versiya), lakin digər dillərdə bölünməyə oxşar bir şey üçün - orijinal məsələdə başa düşdüm ki, mən qərara gəldim:

 IN="bla@some.com;john@home.com" declare -aa="(${IN/;/ })"; 

İndi ${a[0]} , ${a[1]} , və s. Gözlədiyiniz kimi. Şərtlərin sayı üçün ${#a[*]} istifadə edin. Və ya əlbəttə ki, təkrarlayın:

 for i in ${a[*]}; do echo $i; done 

Vacib qeyd:

Bu, mənim problemimi həll edən problemlər olmadığında, problemin həll olunmaması halında işləyir. Bu halda $IFS həlli ilə gedin.

2
22 окт. cavab 22 oktyabr eukras verilir . 2012-10-22 10:10 '12 saat 10:10 'da 2012-10-22 10:10

Yaxşı uşaqlar!

İşdə cavabım!

 DELIMITER_VAL='=' read -d '' F_ABOUT_DISTRO_R <<"EOF" DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.4 LTS" NAME="Ubuntu" VERSION="14.04.4 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.4 LTS" VERSION_ID="14.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" EOF SPLIT_NOW=$(awk -F$DELIMITER_VAL '{for(i=1;i<=NF;i++){printf "%s\n", $i}}' <<<"${F_ABOUT_DISTRO_R}") while read -r line; do SPLIT+=("$line") done <<< "$SPLIT_NOW" for i in "${SPLIT[@]}"; do echo "$i" done 

Niyə bu yanaşma mənim üçün "yaxşı"?

İki səbəbə görə:

  • Separatı gizlətməyə ehtiyac yoxdur ;
  • Boşluqlarla probleminiz olmayacaq. Qiyamət düzgün array bölünür!

[] 's

1
04 апр. Cavab Eduardo Lucio 04 Apr 2016-04-04 22:54 '16 saat 10:54 'da 2016-04-04 22:54

Bash dizilərinin tələb olunmadığı iki bourne-ish alternativi:

1-ci vəziyyət : gözəl və sadədir: NewLine-ni rekord ayırıcı kimi istifadə edin ... məsələn.

 IN="bla@some.com john@home.com" while read i; do # process "$i" ... eg. echo "[email:$i]" done <<< "$IN" 

Qeyd: bu ilk halda, subprocess siyahısı manipulyasiya dəstəkləmək üçün istifadə edilmir.

Fikir: NL'yi özünüz içərisində istifadə etmək və kənardan son nəticə yaratdıqda yalnız bir RS-yə çevirmək faydalı ola bilər.

Vəziyyət 2 : ";" bir rekord ayırıcı kimi ... məsələn.

 NL=" " IRS=";" ORS=";" conv_IRS() { exec tr "$1" "$NL" } conv_ORS() { exec tr "$NL" "$1" } IN="bla@some.com;john@home.com" IN="$(conv_IRS ";" <<< "$IN")" while read i; do # process "$i" ... eg. echo -n "[email:$i]$ORS" done <<< "$IN" 

Hər iki halda, alt siyahı dövrünün sonundan sonra daimi olan bir dövrü tərtib edilə bilər. Bu, yaddaş siyahılarını manipulyasiya edərkən, faylları siyahıda saxlayarkən faydalıdır. {Subscription sakit saxlamaq və davam B-)}

1
02 сент. Cavab verildi NevilleDNZ 02 Sentyabr. 2013-09-02 09:30 '13 saat 09:30 'da 2013-09-02 09:30

$@ Array yükləmək üçün daxili set istifadə edin:

 IN="bla@some.com;john@home.com" IFS=';'; set $IN; IFS=$' \t\n' 

Sonra partiya başlayın:

 echo $# for a; do echo $a; done ADDR1=$1 ADDR2=$2 
1
30 апр. Cavab 30 apr cəbr verilir . 2013-04-30 06:10 '13 'da 6:10' da 2013-04-30 06:10

Android kabuğunda təklif olunan üsulların əksəriyyəti sadəcə işləmir:

 $ IFS=':' read -ra ADDR <<<"$PATH" /system/bin/sh: can't create temporary file /sqlite_stmt_journals/mksh.EbNoR10629: No such file or directory 

İş nədir:

 $ for i in ${PATH//:/ }; do echo $i; done /sbin /vendor/bin /system/sbin /system/bin /system/xbin 

burada // qlobal dəyişdirmə deməkdir.

1
20 февр. Cavab verilir 18446744073709551615 20 fevral. 2015-02-20 13:49 '15 at 13:49 2015-02-20 13:49

Artıq verilmiş olan fantastik cavablara əlavə olaraq, yalnız siyahı məlumatları məsələsində, awk istifadə edə bilərsiniz:

 awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "$IN" 

Bu, sahəsi ayırıcısını təyin edir ; beləliklə bir for loop ilə sahələrdən keçir və müvafiq olaraq çap edə bilərsiniz.

Test et

 $ IN="bla@some.com;john@home.com" $ awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "$IN" > [bla@some.com] > [john@home.com] 

Başqa bir girişlə:

 $ awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "a;b;cd;e_;f" > [a] > [b] > [cd] > [e_] > [f] 
1
08 янв. Cavab fedorqui Jan 08 tərəfindən verilir 2015-01-08 13:21 '15 at 1:21 pm 2015-01-08 13:21

Bəlkə də bu ən zərif həll deyil, ancaq * və boşluqlarla işləyir:

 IN="bla@so me.com;*;john@home.com" for i in `delims=${IN//[^;]}; seq 1 $((${#delims} + 1))` do echo "> [`echo $IN | cut -d';' -f$i`]" done 

Çıxışlar

 > [bla@so me.com] > [*] > [john@home.com] 

Başqa bir nümunə (başlanğıcda və sonunda ayırıcılar):

 IN=";bla@so me.com;*;john@home.com;" > [] > [bla@so me.com] > [*] > [john@home.com] > [] 

Əsasən hər bir xarakterdən başqa silmək ; məsələn, delims hazırlamaq. ;;; . Sonra ${#delims} hesabı ilə 1 dən number-of-delimiters for döngəni icra edir. Son addım cut $i hissəsini təhlükəsiz ala cut .

0
26 февр. Cavab Petr Újezdský tərəfindən verilir 26 fevral. 2016-02-26 15:20 '16 saat 15:20 'də 2016-02-26 15:20
 IN='bla@some.com;john@home.com;Charlie Brown <cbrown@acme.com;!"#$% are no problem;simple is beautiful :-)' set -f oldifs="$IFS" IFS=';'; arrayIN=($IN) IFS="$oldifs" for i in "${arrayIN[@]}"; do echo "$i" done set +f 

Nəticə:

 bla@some.com john@home.com Charlie Brown <cbrown@acme.com !"#$% are no problem simple is beautiful :-) 

Explanation: Bir IFS ilə bağlı sadə bir tapşırıq () bu nöqtədə düzgün bir IFS varsa, nöqtəli vergüllə ayrılmış siyahısını bir sıra çevirir. FOR for loop üçün standart hər bir elementdə fərdi elementləri işləyir. Dəyişən IN üçün göstərilən siyahı "ağır" olmalıdır, yəni qeyd edin. Tək tics ilə.

IFS saxlanılmalı və bərpa edilməlidir, çünki Bash, hədəfə və rəhbərliyə tətbiq edilmir. Alternativ həlli funksiyanı içərisində tapşırıqları kəsmək və bu funksiyanı dəyişdirilmiş IFS ilə çağırmaqdır. Bu halda IFS-in ayrı saxlanması / bərpası tələb olunmur. Bunun üçün "bizə" təşəkkür edirik.

0
10 окт. 10 oktyabrda ajaaskel tərəfindən verilmiş cavab . 2014-10-10 14:33 '14 14:33 2014-10-10 14:33
  • 1
  • 2

bağlı digər suallar və ya sual