Wie initialisiert man ein Array mit awk und bash?

Wie initialisiert man ein Array mit awk und bash?

Ich versuche, die Werte der ersten Zeile einer Textdatei in einem Array zu speichern. Hier ist, was ich bisher habe:

arr_values=()

awk '
    NR==1 {
            for (i=0; i<=NF; i++)
               'arr_values[i]'=$i            #error here
          }' file.txt

for ((i=0; i<${#arr_values[@]}; i++))
do
   echo ${arr_values[i]}
done

Ich erhalte einen Fehler beim Initialisieren des Arrays, hauptsächlich weil ich nicht weiß, wie ich awkein externes Array initialisieren kann. Irgendwelche Vorschläge (nur mit awk)? Danke.

Entschuldigen Sie das Crossposting, ich habe nicht die gewünschte Antwort erhalten.

Antwort1

Sie erhalten möglicherweise bessere Antworten, wenn Sie den Kontext erläutern,Warum awk... und wie die erste Datenzeile aussieht.

Da Sie den Feldtrenner nicht geändert haben, gehe ich davon aus, dass Sie eine Zeile mit durch Leerzeichen getrennten Elementen verarbeiten. Folgendes wird genau das tun, wonach Sie suchen:

arr_values=()

read -ra arr_values <<< $(head -n 1 file.txt)

for s in "${arr_values[@]}"; do
    echo "$s"
done

Die ganze Arbeit wird im readBefehl erledigt. Sofern Sie die Werte in einem Array nicht mehrfach verarbeiten müssen, können Sie einfach Folgendes tun:

set -f    # disable globbing, in case the lines contain wildcard characters
for s in $(head -n 1 file.txt); do
    set +f
    echo "$s"
done
set +f

Dadurch wird jeder durch Leerzeichen getrennte Feldeintrag, der nicht leer ist, eingefügt $sund ein Durchlauf durch die Schleife durchgeführt.

Antwort2

So genau geht das nicht. Sie müssen den awk-Befehl ausführen lassen, eine Reihe von Ausgabewerten erstellen, die durch ein Trennzeichen (Leerzeichen, Tabulator, NUL oder etwas anderes) abgegrenzt sind, und diese dann den Array-Elementen zuweisen. Der Grund dafür ist, dass awk ein Programm ist, das von der Shell ausgeführt wird und bis zum Ende ausgeführt wird, bevorbeliebigweitere Shell-Operationen werden ausgeführt. Sie können Shell-Sachen nicht auf diese Weise in Ihre Awk-Sachen einbetten.

Sie können etwas wie das Folgende tun, um Ihr einfaches Beispiel zu verwenden, aber ich bin nicht sicher, ob der von Ihnen bereitgestellte AWK-Code in jedem Fall das bewirkt, was Sie möchten. Wenn eine Datei null oder mehr als einen Datensatz hat, enthält die Ausgabe (und damit das Shell-Array) die Zeilen der Datei. Es sieht so aus, als ob Sie möchten, dass das Ausgabe-Array eine Reihe von Ganzzahlen von Null bis zur Anzahl der Felder enthält, die Sie in einer Datei finden, genau dann, wenn sie nur einen Datensatz enthält. Wenn Sie vermeiden möchten, dass größere Dateien im Array angezeigt werden, müssen Sie dem AWK-Code eine zweite musterlose Aktion hinzufügen, die nur "{ }" als Aktion enthält, wie ich es unten getan habe. Deaktivieren Sie außerdem die Platzhaltererweiterung für Dateinamen ( set -f), falls die Zeile Platzhalterzeichen enthält \[*?.

set -f
arr_values=(`awk '
    NR==1 {
            for (i=0; i<=NF; i++)
               print $i
          }

          { }' file.txt`)
set +f
for ((i=0; i<${#arr_values[@]}; i++))
do
   echo "${arr_values[i]}"
done

Antwort3

Wenn Sie verwenden möchten awk, können Sie wie folgt vorgehen:

arr_values=( $(awk '{print;exit}' file) )

Die Shell führt die Aufteilung bei Leerzeichen durch. Beachten Sie, dass, wenn die Zeile Platzhalter enthält, diese in die Liste der übereinstimmenden Dateien (sofern vorhanden) erweitert werden. set -fDeaktivieren Sie die Platzhaltererweiterung.

set -f
arr_values=( $(awk '{print;exit}' file) )
set +f

Antwort4

Wie das sonst ist, weiß ich nicht, aber wenn Sie nach Leerzeichen teilen, wird hier die erste Zeile einer Textdatei im Shell-Array gespeichert und nach Leerzeichen geteilt:

set -f ; set -- $(head -n1 <textfile) ; set +f

Das ist alles, was nötig ist. Jetzt sind Ihre Positionsparameter die verschiedenen Array-Indizes und Ihr Array ist "$@".

verwandte Informationen