Datei in shellscript Zeilenweise einlesen

S

Schwedeii

Tripel-As
Eine Frage an die Linux-Gemeinde:
Wie kann ich in einem Bash-Script eine Datei Zeilenweise einlesen und das Ergebnis als Parameter übergeben lassen?

Nach dem Motto

i=1
while [ $i <>0 ]
do
Datei öffnen und Zeile i einlesen
if eof then i=-1
fi
Verarbeite Zeile
let i=$i+1
done


So oder in der Art will ich es gestalten.
 
Ich versteh irgendwie nicht, warum du es so kompliziert machst.
Suchmaschine -> "bash datei zeilenweise" -> Erste paar Treffer anschauen

Einfache Lösungen:
Code:
#Einzeiler
cat /pfad/zu/datei | while read line; do echo $line; done;

#Mehrzeiler
while read line
do
    echo $line
done < /pfad/zu/datei

Gruß Always-Godlike
 
Ich benutze das prinzip um Songs aus einer Playliste auf mein Handy zu speichern:
Dateien aus einer Dateiliste kopieren:
Code:
a) for i in $(cat playlist.pl); do cp ${i} /mnt/Music/mp3/; done
b) while read i; do cp "${i}" /mnt/Music/mp3/; done < playlist.pl

wobei "playlist.pl" so aussieht:
Code:
/path/to/file1.mp3
/path/to/file2.mp3
/path/to/file3.mp3

Also ich denke das es das ist was du willst?

Lg Manuel
 
Zuletzt bearbeitet:
okay, ganz einfach, ich will die Daten aus einer *.m3u Playlist mit mpg123 abspielen lassen. Der Hintergrund ist der, dass ich den Rechner als mp3-Player eine Liste abspielen lassen will und am Anschluss soll er sich herunterfahren. In einem Script eben.
 
Haja, kannst doch genau so benutzen. grep dir halt vorher den Pfad raus.
 
Zuletzt bearbeitet:
Code:
# Setzen des Fieldseperators auf eine neue Zeile
IFS="
"
# Loop durch die Datei
for line in `cat /tmp/files`;do
# Echo line (echo kann jeder Befehl sein den du willst)
 echo $line
done
 
Das hat schon erst mal gut funktioniert. Leider speichert die *.m3u Liste in folgendem Format:
#EXTM3U
#EXTINF:68,Willkommen - Schiller
/media/disk/Schiller/101-Willkommen.mp3
#EXTINF:249,Herzschlag - Schiller
/media/disk/Schiller/102-Herzschlag.mp3
#EXTINF:236,Denn wer liebt (mit Anna Maria Muehe) - Schiller
/media/disk/Schiller/103-Denn_wer_liebt_(mit_Anna_Maria_Muehe).mp3

Also muss ich die Zeile so auswerten, dass nur die Zeilen, die nicht mit einer Raute anfangen auch abgespielt werden... Wie macht man sowas? ich muss hier noch viel lernen...
 
In Anlehnung an diesen Thread vor kurzem:

Ersetze das
Code:
echo $line
aus T-One's Vorschlag z.Bsp. durch

Code:
if [ $(echo "$line" | grep ^[/]) ]; then
 #doit
fi;

und es sollten nur Zeilen abgearbeitet werden, die mit / anfangen.
 
Zuletzt bearbeitet:
Auch interessant, ich habe es aber nach googeln auch hingekriegt und zwar so:

case "$line" in
"#"*) echo $line ;;
*) echo "spiele " $line
mpg123 $line ;;
esac

Danke für Eure Hilfe.
 
In Anlehnung an diesen Thread vor kurzem:

Ersetze das
Code:
echo $line
aus T-One's Vorschlag z.Bsp. durch

Code:
if [ $(echo "$line" | grep ^[/]) ]; then
 #doit
fi;

und es sollten nur Zeilen abgearbeitet werden, die mit / anfangen.

Oder umgekehrt die, die nicht mit einem # beginnen, es täte dann auch ein
echo $line | grep -v "^#"
 
Oder
Code:
 grep ^[^#]
statt dem Schalter... (Aber ungetestet)

(^ vor der Klammer für Zeilenanfang, ^ vor dem Zeichen für "Nicht das Zeichen")
 
Naja, das kling gut und schön, aber die Programmierung sollte weitergehen. M3u Dateien können auch andere Media-Files enthalten. mpg123 kann diese aber nicht wiedergeben. Ich hab das so gelöst:
case "$line" in
"#"*) echo $line ;;
*".mp3") echo "spiele " $line
mpg123 $line ;;
*) echo "keine Auswertung" $line;;
esac
 
So, der nächste Schritt war, über eine Dialogbox den Namen der Playlist einzugeben. das funktioniert auch ganz gut, nur wird das Ziel in /etc/dream/playlist auch dann überschrieben (der Datensatz wird gelöscht) wenn ich auf abbrechen klicke. Was mache ich falsch?
Hier das Listing:
#!/bin/sh

# Setzen des Fieldseperators auf eine neue Zeile
IFS="
"
#Dialogbox für die playlist
dialog --inputbox "Bitte Playlist eingeben" 0 0 2> /etc/dream/playlist

for list in `cat /etc/dream/playlist`;do

# Loop durch die Datei
for line in `cat $list`;do
# Echo line (echo kann jeder Befehl sein den du willst)

case "$line" in
"#"*) echo $line ;;
*".mp3") echo "spiele " $line
mpg123 $line ;;
*) echo "keine Auswertung" $line;;
esac
done
done
 
Hi,
[...] nur wird das Ziel in /etc/dream/playlist auch dann überschrieben (der Datensatz wird gelöscht) wenn ich auf abbrechen klicke. Was mache ich falsch?
du leitest den output von
Code:
dialog --inputbox "Bitte Playlist eingeben" 0 0 2> /etc/dream/playlist
bedingunglos nach /etc/dream/playlist um. D.h. auch wenn dialog keinen output hat, wird die alte Datei ueberschrieben und neu angelegt.
Du solltest den output lieber in eine Variable schreiben, und die Datei erst schreiben, wenn dialog erfolgreich ausgefuehrt wurde (test auf $?).

<edit>
Ah, ich sehe gerade dass dialog die Ausgabe auf stderr legt, wie du in deinem Skript ja auch richtig geschrieben hast. Ich weiss gar nicht ob man stderr mit einer Variable einfangen kann. Du kannst aber genauso gut natuerlich erstmal eine temporaere Datei benutzen.
</edit>

Aber bist du dir sicher, dass du nach /etc/ schreiben willst? Das sieht mir stark nach einer benutzerabhaengigen Einstellung aus, dann solltest du das lieber in ~/.dream/playlist schreiben...

Nebenbei, wenn du statt Zitat Bloecken Code Bloecke benutzt, bleiben auch die Einrueckungen des Codes erhalten.

mfg,
bytepool
 
Zuletzt bearbeitet:
Nun sieht es so aus:

Code:
#!/bin/sh

# Setzen des Fieldseperators auf eine neue Zeile
IFS="
"
#Dialogbox für die playlist
dialog --inputbox "Bitte Playlist eingeben" 0 0 2> /etc/dream/playlist.new
clear

echo ">>"$?"<<"
  case "$?" in
     "0") cp /etc/dream/playlist.new /etc/dream/playlist;;
        *) echo;;
  esac

for list in `cat /etc/dream/playlist`;do

  # Loop durch die Datei
  for line in `cat $list`;do
  # Echo line (echo kann jeder Befehl sein den du willst)

    case "$line" in
           "#"*) echo $line ;;
      *".mp3") echo "spiele  " $line
                   mpg123 $line ;;
                *) echo "keine Auswertung" $line;;
     esac
  done
done

Warum mir $? aber ständig den Wert 0 liefert, egal, ob ich <OK> oder <Abbrechen> drücke, bleibt mir ein Rätsel.
 
Warum mir $? aber ständig den Wert 0 liefert, egal, ob ich <OK> oder <Abbrechen> drücke, bleibt mir ein Rätsel.
Hehe, sorry, ich hab noch nie mit dialog gearbeitet, es kann natuerlich gut sein, dass dialog seinen Rueckgabewert nicht von deiner Eingabe abhaengig macht. Ich hatte das jetzt einfach mal vermutet. Wie das genau funktioniert also am besten in der manpage nachlesen. ;)

Edit:
Ein kurzer Blick in die manpage sagt, dass bei Cancel einfach kein Text zurueckgegeben wird. D.h. ich wuerde das wahrscheinlich so machen:
Code:
foo=$(dialog --stdout --inputbox "mach ma was:" 0 0)
if [ ! -z "$foo" ]; then
   echo "jaaaa, es gab input. :)"
fi
mfg,
bytepool
 
Zuletzt bearbeitet:
Hab's gefunden. Dialog liefert bei <Ok> den Wert 0 in $? . Bei Fehler liefert es den Wert <>0. Das Problem liegt darin, dass die Auswertung direkt nach dem Dialog-Befehl erfolgen muss. Das clear nach Dialog hat $? wieder auf 0 gesetzt. Ich habe den Wert von $? nun an $meine übergeben, nun läuft es.
 
Zuletzt bearbeitet:
Hello Freaks !

bin hier neu und habe keine Ahnung von shell scripting. Vielleicht kann sich ja mal jemand meines Problems annehmen.
Eigentlich ähnlich zu dem Threat hier passend
Ich habe auch eine Datei, in der zeilenweise Daten enthalten sind wie diese Zeile hier:

-8.768500,41.837230,"xyz2001a (TYPE)"

nun möchte ich aus den Daten jeder Zeile jeweils eine Datei machen die bis auf die bunten Daten immer gleich sein soll. Ein Beispiel:

BEGIN:VCARD
VERSION:3.0
CATEGORIES:VIP
X-VIPCategory:Misc
ADR;ENCODING=QUOTED-PRINTABLE:;;xyz2001a (TYPE)
X-NAVADDR:;;;;;;;;;
GEO:41.83723;-8.76850
X-Flag:
REV:20140820T191503z
FN;ENCODING=QUOTED-PRINTABLE:xyz2001a (TYPE)
UID:AddresBookPersistentProvider3
END:VCARD

(Der restliche schwarze text bleibt immer gleich)

Wie man sieht, sind die GEO Daten am Ende um eine stelle hinterm Koma gekürzt und können positiv oder negativ sein. Die Ausgabedateiname(n) sollten den ersten 7 Zeichen von xyz2001a entsprechen.
Die 3 Datensätze je zeile sind durch kommas getrennt und der letzte datensatz ist in Anführungszeichen, die weg müssen.


Hoffentlich kann mir jemand dabei helfen....weiss leider nicht mal wie ich anfangen soll..... Linux server (Ubuntu 14.04) lts vorhanden.

vielen Dank im voraus

zyklop
 
Zuletzt bearbeitet von einem Moderator:
Code:
#!/usr/bin/perl -w
use strict;

open DATEI, "testdatei";   # hier stehen deine geodaten drinn

while (<DATEI>) {
 chomp;

 my @daten = split(/,/);

 my $short1 = substr $daten[0], 0, ( length($daten[0])-1 );
 my $short2 = substr $daten[1], 0, ( length($daten[1])-1 );
 my $short3 = substr $daten[2], 1, ( length($daten[2])-2 );

 open AUSGABE, ">" . substr $daten[2], 1, 7;
   
 print AUSGABE "BEGIN:VCARD
VERSION:3.0
CATEGORIES:VIP
X-VIPCategory:Misc
ADR;ENCODING=QUOTED-PRINTABLE:;;$short3
X-NAVADDR:;;;;;;;;;
GEO:$short2;$short1
X-Flag:
REV:20140820T191503z
FN;ENCODING=QUOTED-PRINTABLE:$short3
UID:AddresBookPersistentProvider3
END:VCARD";

close AUSGABE;
}

close DATEI;
 
Zuletzt bearbeitet:

Ähnliche Themen

Switche abfragen über Script

Verschlüsseltes Backup-Script mit rsync

script sshpass

Summe von Zahlen in einer Zeilen bilden

Shell Skript beschleunigen

Zurück
Oben