Çıktı nasıl bölünür ve bir dizide saklanır?


9

Bu çıktı:

3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720

2 senaryo ile denedim:

  1. Bir dizide saklama

      @arr=split(',',$stats);
      echo "statistics: $stats"
    
  2. Değişkende saklama

     echo $stats | cut -d ',' -f | read s1
     echo $s1
    

Ancak her iki senaryo da çalışmıyor.


awk '{ split("3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720 ",arr,","); print arr[1]; }' VEYA echo "3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720" | awk '{ split($0,arr,","); print arr[1]; }' Bu işe yarar.

Yanıtlar:


9

Tek bir girdi satırı için böyle bir şey kullanabilirsiniz:

IFS="," read -ra arr <<< "$foo"

Demo:

$ cat t.sh 
foo="3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, ..." # snipped

IFS="," read -ra arr <<< "$foo"
echo ${#arr[@]}
echo ${arr[0]}
echo ${arr[30]}
$ ./t.sh 
31
3
1280 720

Kredi: bash sınırlayıcı dayalı bölünmüş dize? cevap Johannes Schaub . Oradaki diğer cevapları da kontrol edin.


2

İlk snippet'iniz kabuk sözdizimi gibi bir şey değil. Doğru Perl sözdizimi.
İkinci snippet'iniz cutdoğru şekilde kullanılmıyor; Ne istediğini bilmiyorum.

Kabuk yerleşik bir dize bölme yapısına sahiptir: $somevartırnak işaretleri olmadan yazdığınızda , kabuk önce değişkenin değerini arar somevar, sonra bu değeri belirtilen karakterlerde ayrı kelimelere böler IFSve son olarak her kelimeyi bir glob olarak yorumlar desen (dosya joker karakteri). Böylece IFS, ayırıcı karaktere ayarlayıp geçici olarak globbing'i kapatarak bir dizeyi bölebilirsiniz .

set -f; IFS=,
arr=($stats)
set +f; unset IFS

Bir alan boşluk içeriyorsa, dizi öğesinin boşluk olduğunu koruyacağını unutmayın. Tüm boşluklara ve virgüllere bölmek istiyorsanız, ayarlayın IFS=', '. Not IFSat bölünmüş ama en bölünmeye karakter kümesine bir dize değil; bir boşluk veya virgül bir ayırıcı oluşturacaktır. Dahası, boşluk için özel kurallar vardır: sıfır veya daha fazla boşluktan oluşan herhangi bir sekans, ardından sıfır veya daha fazla boşluk izleyen bir virgül bir ayırıcı, ve bir veya daha fazla boşluktan oluşan herhangi bir sekans da bir ayırıcı oluşturacaktır.

Yalnızca bir alanın başında veya sonunda boşluk bırakmak istiyorsanız, bunu tek tek yapmanız gerekir.

shopt -s extglob
for ((i=0; i<${#arr[@]}; i++)); do
  arr[i]=${arr[i]#+( )}   # strip one or more spaces at the beginning
  arr[i]=${arr[i]%+( )}   # strip one or more spaces at the end
done

2
$ set -f  # turn off globbing, so as not to expand wildcards
$ arr=($(echo "$stats" | sed 's/,/ /g'))
$ echo ${arr[1]}
aac-lc

1
Bunun boşlukları virgüllerin yanı sıra ayırıcılar olarak ele alacağını unutmayın.
Gilles 'SO- kötü olmayı bırak'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.