Hoe splits ik een gescheiden string in een array in awk?

Hoe de string te splitsen als deze pipe-symbolen |bevat.
Ik wil ze splitsen om in een array te staan.

Ik heb het geprobeerd

echo "12:23:11" | awk '{split($0,a,":"); print a[3] a[2] a[1]}'

Wat prima werkt. Als mijn string is zoals "12|23|11", hoe splits ik ze dan in een array?


Antwoord 1, autoriteit 100%

Heb je geprobeerd:

echo "12|23|11" | awk '{split($0,a,"|"); print a[3],a[2],a[1]}'

Antwoord 2, autoriteit 43%

Om een string te splitsen naar een array in awkgebruiken we de functie split():

awk '{split($0, a, ":")}'
 #           ^^  ^  ^^^
 #            |  |   |
 #       string  |   delimiter
 #               |
 #               array to store the pieces

Als er geen scheidingsteken wordt gegeven, gebruikt het de FS, die standaard de spatie is:

$ awk '{split($0, a); print a[2]}' <<< "a:b c:d e"
c:d

We kunnen een scheidingsteken geven, bijvoorbeeld ::

$ awk '{split($0, a, ":"); print a[2]}' <<< "a:b c:d e"
b c

Wat gelijk staat aan het instellen via de FS:

$ awk -F: '{split($0, a); print a[1]}' <<< "a:b c:d e"
b c

In gawk kun je het scheidingsteken ook als regexp opgeven:

$ awk '{split($0, a, ":*"); print a[2]}' <<< "a:::b c::d e" #note multiple :
b c

En zelfs zien wat het scheidingsteken was bij elke stap door de vierde parameter te gebruiken:

$ awk '{split($0, a, ":*", sep); print a[2]; print sep[1]}' <<< "a:::b c::d e"
b c
:::

Laten we de man-pagina van GNU awkciteren :

split(string, array [, fieldep [, seps ] ])

Verdeel stringin stukjes gescheiden door fieldsepen sla de stukjes op in arrayen de scheidingstekens in de sepsarray. Het eerste stuk wordt opgeslagen in array[1], het tweede stuk in array[2], enzovoort. De tekenreekswaarde van het derde argument, fieldsep, is een regexp die beschrijft waar stringmoet worden gesplitst (zoals FSeen regexp kan zijn die beschrijft waar invoerrecords splitsen). Als fieldsepwordt weggelaten, wordt de waarde van FSgebruikt. split()geeft het aantal gemaakte elementen terug. sepsis een gawkextensie, waarbij seps[i]het scheidingsteken is tussen array[i]en array[i+1]. Als fieldsepeen enkele spatie is, dan gaat elke voorafgaande witruimte in seps[0]en elke volgende witruimte gaat in seps[n], waar nis de retourwaarde van split()(dwz het aantal elementen in de array).


Antwoord 3, autoriteit 6%

Wees alstublieft specifieker! Wat bedoel je met “het werkt niet”?
Post de exacte uitvoer (of foutmelding), uw besturingssysteem en awk-versie:

% awk -F\| '{
  for (i = 0; ++i <= NF;)
    print i, $i
  }' <<<'12|23|11'
1 12
2 23
3 11

Of gebruik splitsen:

% awk '{
  n = split($0, t, "|")
  for (i = 0; ++i <= n;)
    print i, t[i]
  }' <<<'12|23|11'
1 12
2 23
3 11

Bewerken: op Solarismoet je de POSIXawk (/usr/xpg4/bin/awk) gebruiken om verwerk 4000 velden correct.


Antwoord 4, Autoriteit 2%

Ik hou niet van de echo "..." | awk ...OPLOSSING ALS HET ONTVANGEN UNNESHEID forkEN execSYSTEEM CALTER.

Ik geef de voorkeur aan de oplossing van een Dimitre met een kleine draai

awk -F\| '{print $3 $2 $1}' <<<'12|23|11'

of een beetje kortere versie:

awk -F\| '$0=$3 $2 $1' <<<'12|23|11'

In dit geval wordt het uitvoerrecord samengesteld, wat een echte voorwaarde is, zodat deze wordt afgedrukt.

In dit specifieke geval kan de stdinomleiding worden gespaard met het instellen van een AWK Interne variabele:

awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}'

Ik gebruikte KSH behoorlijk een tijdje, maar In bash Dit kan worden beheerd door interne snaarmanipulatie. In het eerste geval wordt de originele string gesplitst door interne terminator. In het tweede geval wordt aangenomen dat de tekenreeks altijd een cijferparen bevat die worden gescheiden door een één tekenscheider.

T='12|23|11';echo -n ${T##*|};T=${T%|*};echo ${T#*|}${T%|*}
T='12|23|11';echo ${T:6}${T:3:2}${T:0:2}

Het resultaat in alle gevallen is

112312

Antwoord 5

Eigenlijk awkheeft een functie genaamd ‘Input Field Separator-variabele’ link . Dit is hoe het te gebruiken. Het is niet echt een array, maar het gebruikt de interne $ variabelen. Voor het splitsen van een eenvoudige string is het gemakkelijker.

echo "12|23|11" | awk 'BEGIN {FS="|";} { print $1, $2, $3 }'

Antwoord 6

echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

zou moeten werken.


Antwoord 7

echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

Antwoord 8

Ik weet dat dit een soort van oude vraag is, maar ik dacht dat iemand misschien als mijn truc is. Vooral omdat deze oplossing niet beperkt tot een specifiek aantal items.

# Convert to an array
_ITEMS=($(echo "12|23|11" | tr '|' '\n'))
# Output array items
for _ITEM in "${_ITEMS[@]}"; do
  echo "Item: ${_ITEM}"
done

De uitvoer is:

Item: 12
Item: 23
Item: 11

Antwoord 9

Joke? 🙂

Hoe zit het met echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

Dit is mijn uitvoer:

p2> echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'
112312

Dus ik denk dat het ten goede werkt ..


Antwoord 10

De Challenge : parseren en opslaan splitsen met spaties en plaats ze in variabelen.

Oplossing: Beste en eenvoudige keuze voor u zou omzetten in de reeksenlijst in de array en verminder het dan in variabelen met indexen. Hier is een voorbeeld hoe u de array kunt converteren en openen.

Voorbeeld: Ontspanning schijfruimte Statistieken op elke regel:

sudo df -k | awk 'NR>1' | while read -r line; do
   #convert into array:
   array=($line)
   #variables:
   filesystem="${array[0]}"
   size="${array[1]}"
   capacity="${array[4]}"
   mountpoint="${array[5]}"
   echo "filesystem:$filesystem|size:$size|capacity:$capacity|mountpoint:$mountpoint"
done
#output:
filesystem:/dev/dsk/c0t0d0s1|size:4000|usage:40%|mountpoint:/
filesystem:/dev/dsk/c0t0d0s2|size:5000|usage:50%|mountpoint:/usr
filesystem:/proc|size:0|usage:0%|mountpoint:/proc
filesystem:mnttab|size:0|usage:0%|mountpoint:/etc/mnttab
filesystem:fd|size:1000|usage:10%|mountpoint:/dev/fd
filesystem:swap|size:9000|usage:9%|mountpoint:/var/run
filesystem:swap|size:1500|usage:15%|mountpoint:/tmp
filesystem:/dev/dsk/c0t0d0s3|size:8000|usage:80%|mountpoint:/export

Other episodes