Verwenden von Sed Ampersand Substitution mit Array

1

Ich versuche, das kaufmännische Und-Zeichen von sed zu verwenden, um es durch die ursprüngliche Zeichenfolge zu ersetzen, und dann aus dem Array zu lesen, aber es funktioniert nicht. Ich bekomme nur den Fehler: 'Operand erwartet (Fehlertoken ist "&")'.

Hier ist die entsprechende Codezeile:

gawk -F '\t' '{ print $5"\t"$1"\t"$2"\t"$3"\t"$4 }' $TEMPFILE | sed "s/^[0-9]\+/${CATEGORY[&]}/g"

Die erste Gawk-Anweisung erzeugt am Zeilenanfang eine zweistellige Zahl. Wenn ich das kaufmännische Und in der sed-Anweisung manuell durch diese Nummer ersetze, funktioniert alles. Ich würde mich sehr über Hilfe freuen.

Sarah C. Corriher
quelle

Antworten:

3

Das Problem ist, dass die Shell zuerst die Zeichenfolge in Anführungszeichen erweitert und dann die erweiterte Zeichenfolge als Parameter an sed sendet. Sed weiß jedoch nicht, wie man Shell-Variablen erweitert.

Sie sollten dies jedoch awkdirekt tun können :

category=(red amber green)
awk -f <( # This generates the awk code:
          echo '{';
          for (( i=0; i<${#category[@]}; i++ )) ; do
              echo category"[$i]"=\"${category[$i]}\"
          done
          echo 'print $1, category[$1]}'
      ) <( # This is the input file. 
          echo 0; echo 1 ; echo 2 )
Choroba
quelle
Ich bin nicht so vertraut mit komplexen awk-Anweisungen, aber dieser Code scheint einfach nicht zu funktionieren. Das einzige, was gedruckt wird, ist die Zahl, die Sie am Ende zurückgegeben haben.
Sarah C. Corriher
@ SarahC.Corriher: Aktualisiert mit der categoryZuordnung.
Choroba
1

Wie Choroba betonte, besteht Ihr Problem darin, dass Ihre Muschel versucht, sich auszudehnen, ${CATEGORY[something]}bevor Sie sie an Sed weitergibt.

Wenn Sie dies unbedingt mit einer Pipe von awk nach sed tun möchten, ist dies eine Problemumgehung:

awk ... | sed 's/^[0-9]\+/echo ${CATEGORY[&]}/g' | bash

Es funktioniert mit sed, um Shell-Anweisungen zu erstellen, die das Array lesen. Dies funktioniert immer noch nur, wenn das Array exportiert wird.

Sie können es auch versuchen

eval $(awk ... | sed 's/^[0-9]\+/echo ${CATEGORY[&]}/g')

Dies funktioniert auch, ohne dass das Array exportiert wird.

Ich würde keine der beiden Lösungen empfehlen, es sei denn, Sie können 100% sicher sein, dass Ihr sed-Skript keine gefährlichen Befehle erzeugen kann (auch wenn die Eingabe in awk böswillig ist).

András Korn
quelle
Vielen Dank. Obwohl ich für andere darauf hinweisen möchte, dass die Anführungszeichen um die sed-Anweisung doppelte Anführungszeichen sein müssen, damit dies funktioniert.
Sarah C. Corriher
Nein. Wenn es sich um doppelte Anführungszeichen handelt, versucht die Shell zu expandieren ${CATEGORY[foo]}, wodurch das Skript beschädigt wird (oder ich habe falsch verstanden, was Sie tun möchten). Ich habe einzelne Anführungszeichen verwendet, um dies zu vermeiden, damit sed ${CATEGORY[foo]}wörtlich sehen (und schließlich ausgeben) kann .
András Korn