Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Zeileninhalte in Variablen

1 view
Skip to first unread message

Alexander Goetzenstein

unread,
Nov 13, 2022, 6:37:43 AM11/13/22
to
Hallo,
in der bash möchte ich Variablen die Inhalte einer Textdatei zuweisen.
Auslesen der Datei und Anzeigen der Zeileninhalte geht ja einfach:

> i=1
> cat $FILE | while read LINE
> do
> echo 'Zeile '$i': '"$LINE"
> i=$((i + 1))
> done


Aber wie bekomme ich die Zeilen in Variablen, so dass anschließend etwa

> echo 'erstens: '$ZEILE1', zweitens: '$ZEILE2' und drittens: '$ZEILE3

funktioniert?


--
Gruß
Alex

Marcel Logen

unread,
Nov 13, 2022, 7:20:46 AM11/13/22
to
Alexander Goetzenstein in de.comp.os.unix.shell:
Ich würde mit einem "indexed array" arbeiten.
<https://manpages.debian.org/bullseye/bash/bash.1.en.html#Arrays>

Also etwa so:

"while read" (ohne "LINE"), und dann weiter unten im Script

zeile[$i]="$REPLY"

Dann hast Du $zeile[1], $zeile[2], $zeile[3] usw.

Evtl. "read" noch mit "-r", wenn nötig.
<https://manpages.debian.org/bullseye/bash/bash.1.en.html#read>

Marcel o8hu (795198)
--
╭──────╮ ╭────╮ ╭─────╮ ╭────╮ ╭──────╮ ╭───────╮ ╭─────╮
╰─╮ ╭─╯ ╰──╮ │ ╰──╮ │ ╰─╮ │ ╰────╮ │ ╭─╯ ╰─╯ ╭──╯
╭──╯ ╰──╮ ╭─╯ │ ╭──╯ ╰───────╯ ╰─╮ ╭───╯ │ ╰───╮ ╭───────╯
╯ ╰──╯ ╰──╯ de5850 ╰────╯ ╰──────╯ ╰────────────

Marcel Logen

unread,
Nov 13, 2022, 7:33:49 AM11/13/22
to
Marcel Logen in de.comp.os.unix.shell:

[Array]
>Dann hast Du $zeile[1], $zeile[2], $zeile[3] usw.

Sorry, es muß natürlich

${zeile[1]} etc.

heißen.

Marcel o8sk (795540)
--
╭───────╮ ╭────────╮ ╭─╮ ╭─────╮ ╭──────╮ ╭─
╰─╮ ╭──╯ ╰────╮ ╰──────╯ │ │ ╭──╯ ╰─╮ ╭─╯ │
───╯ ╰───╮ ╭──╮ ╰───────╮ ╰──╯ ╰─╮ ╭───╮ ╭─╯ ╰────────╯
╰─────────╯ ╰──────────╯ ╰─╯ ╰──╯ 9c0f58

Christian Garbs

unread,
Nov 13, 2022, 11:56:59 AM11/13/22
to
Mahlzeit!
Analog zu Deinem Code ginge das so:

#+v

cat $FILE | (
read ZEILE1
read ZEILE2
read ZEILE3
echo 'erstens: '$ZEILE1', zweitens: '$ZEILE2' und drittens: '$ZEILE3
)

#-v

Ob das so sinnvoll ist (die Variablen sind z.B. nur in der Subshell
definiert und Du kannst nicht ohne weiteres über beliebig viele Zeilen
iterieren), kann ich nicht beurteilen, weil ich nicht weiß, was Du
eigentlich tun willst.


Ggf. geht es mit Arrays einfacher. Wann Du das, wie von Marcel
beschrieben, in einer bash machst, kannst Du das Array am Stück
einlesen und brauchst dafür keine Schleife zu bauen. Außerdem kommst
Du um die Subshell drumherum und die Array-Variable steht Dir im
Haupt-Skript zur Verfügung:

#+v

mapfile ZEILE < $FILE
echo 'erstens: '${ZEILE[0]}', zweitens: '${ZEILE[1]}' und drittens: '${ZEILE[2]}

#-v

Obacht, der Index des Arrays fängt (wie üblich) bei 0 an zu zählen.
Das könntest Du aber mit dem Parameter -O bei mapfile ändern.


Gruß
Christian

PS: Ein paar Anmerkungen zu Deinem Code:

1. statt "cat $FILE | ()" könntest Du "() < $FILE" benutzen, das spart
einen unnötigen Aufruf von cat

2. read sollte immer mit -r aufgerufen werden

3. das Quoting beim echo lässt sich vereinfachen zu
echo "erstens: $ZEILE1, zweitens: $ZEILE2 und drittens: $ZEILE3"

--
....Christian.Garbs....................................https://www.cgarbs.de
Die vorsorgliche Hausfrau hat immer eine leere Flasche im Kühlschrank.
Es könnte ja Besuch kommen, der nichts trinken will.

Marcel Logen

unread,
Nov 13, 2022, 12:30:39 PM11/13/22
to
Christian Garbs in de.comp.os.unix.shell:

>Alexander Goetzenstein <alexander_g...@web.de> wrote:

>> in der bash möchte ich Variablen die Inhalte einer Textdatei zuweisen.
>> Auslesen der Datei und Anzeigen der Zeileninhalte geht ja einfach:
[...]
>> Aber wie bekomme ich die Zeilen in Variablen, so dass anschließend etwa
>>
>>> echo 'erstens: '$ZEILE1', zweitens: '$ZEILE2' und drittens: '$ZEILE3
>>
>> funktioniert?

[...]

>#+v
>
>mapfile ZEILE < $FILE
>echo 'erstens: '${ZEILE[0]}', zweitens: '${ZEILE[1]}' und drittens: '${ZEILE[2]}
>
>#-v
>
>Obacht, der Index des Arrays fängt (wie üblich) bei 0 an zu zählen.
>Das könntest Du aber mit dem Parameter -O bei mapfile ändern.

Ah, "mapfile/readarray" ist natürlich optimal für diese Aufgabe.
Das kannte ich noch nicht. Vielen Dank!

Marcel ohnt (804605)
--
╭─╮ ╭──────────╮ ╭──╮ ╭────╮ ╭─╮
│ ╰─╮ ╰───────╮ ╰───────╯ │ ╭─────╮ ╭─╮ │ ╰──╯ │
╯ │ ╭──╮ │ ╭────────╯ │ ╭──╯ │ ╰─╮ ╭────╮ ╭─╯ ╰─╮
╰───╯ ╰───╯ ╰───────────╯ ╰─────╯ ╰─╯ ╰─╯ 3c641a ╰──╮

Alexander Goetzenstein

unread,
Nov 13, 2022, 12:57:23 PM11/13/22
to
Hallo,
Dir und auch Marcel einen herzlichen Dank! So habe ich wieder etwas gelernt.

Am 13.11.22 um 17:56 schrieb Christian Garbs:
Gruß
Alex

Jan Novak

unread,
Nov 14, 2022, 1:08:21 AM11/14/22
to
Am 13.11.22 um 12:37 schrieb Alexander Goetzenstein:
Du könntest in einer for Schleife die Zeilen anhand des "\n" trennen.
Dafür gibt es mehrere Möglichkeiten. Eine wäre IFS entsprechend zu
setzen (IFS=$'\n' / IFS=$' ')

Jan

Rolf Buenning

unread,
Nov 14, 2022, 2:12:09 AM11/14/22
to
Christian Garbs <mi...@cgarbs.de> schrieb:

> #+v
>
> cat $FILE | (
> read ZEILE1
> read ZEILE2
> read ZEILE3
> echo 'erstens: '$ZEILE1', zweitens: '$ZEILE2' und drittens: '$ZEILE3
> )
>
> #-v

Modus Korintenkackerei = ein

das sollte oben heißen
#v+
und
#v-

Christian Garbs

unread,
Nov 14, 2022, 11:50:52 AM11/14/22
to
Mahlzeit!

Rolf Buenning <r.bue...@gmx.de> wrote:

> Modus Korintenkackerei = ein
>
> das sollte oben heißen
> #v+
> und
> #v-

Danke, ich kann mir das nie merken.

Ich hab gegoogelt und nach irgendeiner Suchanfrage ähnlich "usenet
verbatim #" hat mir die Autovervollständigung im Suchfeld "#+v"
vorgeschlagen…

Pusht das Thema bitte alle mal im Google-Index, damit ich das beim
nächsten Mal schneller und vor allem richtig herum finde ;-)

Gruß
Christian
--
....Christian.Garbs....................................https://www.cgarbs.de
Kommt ein Huhn in den Elektroladen:
"Ich hätte gerne eine Legebatterie!"

Stefan Reuther

unread,
Nov 14, 2022, 1:35:23 PM11/14/22
to
Am 13.11.2022 um 12:37 schrieb Alexander Goetzenstein:
>> i=1
>> cat $FILE | while read LINE
>> do
>> echo 'Zeile '$i': '"$LINE"
>> i=$((i + 1))
>> done
>
> Aber wie bekomme ich die Zeilen in Variablen, so dass anschließend etwa
>
>> echo 'erstens: '$ZEILE1', zweitens: '$ZEILE2' und drittens: '$ZEILE3
>
> funktioniert?

Schon wegen der Tatsache, dass die Pipe dir eine Subshell spendiert,
gegen die du dann ankämpfen darfst, würde ich bei Aufgaben der Art dann
doch ernsthaft drüber nachdenken, die Verarbeitungslogik in einer
Skriptsprache wie Perl zu machen.

Zumindest wenn du dich dafür auf eine bestimmte Shell festlegen musst,
und somit eh keine POSIX-Portabilität mehr hast, kannst du auch gleich
den Folgeschritt noch tun.


Stefan
0 new messages