ubuntuusers.de

sed in Schleife Problem

Status: Gelöst | Ubuntu-Version: Lubuntu 22.04 (Jammy Jellyfish)
Antworten |

Marantkurz

Anmeldungsdatum:
7. September 2023

Beiträge: 941

sed bringt wenn Bedingung erfüllt ist: "kann nicht bearbeitet werden: Das ist keine normale Datei". Verständlich, und ich weiss nicht weiter. Bitte um Hilfe.

1
2
3
4
while read line; do
	echo "zeile: $line"
	if [ -d $line ]; then sed -i "s,$,/*," $line;fi
done  <  ~/quelle

Bearbeitet von rklm:

Syntaxhighlighting

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4695

Wohnort: Berlin

Wenn Dir das klar ist, dann verstehe ich jetzt nicht so ganz warum Du das so machst‽ Was soll denn mit dem Verzeichnis passieren? Oder willst Du das gar nicht bei Verzeichnissen machen sondern bei Dateien? Dann ist die Bedingung halt falsch. Gibt ja auch einen Test auf Datei.

Edit: Ich würde $line treffender benennen. Ja klar ist das auch eine Zeile, aber es wird ja als Pfad verwendet, also vielleicht besser $path.

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 941

Ja, Verzeichnisse sollen "/*" bekommen.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4695

Wohnort: Berlin

Verzeichnisse haben keinen Inhalt den man mit sed bearbeiten könnte. Die haben höchstens einen Namen den man mit mv ändern kann, aber Namen dürfen den Pfadtrenner / nicht enthalten. * schon, aber das kann lustig werden solange man nicht mit ordentlichen Programmiersprachen arbeitet.

Du müsstest wohl mal etwas weiter ausholen und beschreiben was Du da für Daten, Datei- und Verzeichnisnamen hast, und was Du erreichen möchtest, und vielleicht auch warum.

Edit: Kann es sein, dass Du etwas in dieser Art willst:

1
2
3
4
5
6
7
while read -r path; do
     if [ -d path ]; then
          echo "$path/*"
     else
          echo "$path"
     fi
done < ~/quelle

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 941

Das bringt mich nicht weiter. Die echo Ausgabe nützt nun wirklich nichts. War bei mir nur drin zwecks Nachverfolgung. Das Problem wird ja sed sein. sed ist nicht mein Ding(glaube aber langsam wirds besser 😬), war froh, das überhaupt so hinbekommen zu haben.

In Deinem Beispiel war der Fehlerteufel aktiv. Falls Jemand auf die Idee kommt das zu probieren.

if [ -d $path ]; then

**

Ursprungstateien sind m3u. Also Text mit Zeilenumbruch.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4695

Wohnort: Berlin

Ich dachte halt Du wolltest vielleicht den Inhalt von ~/quelle ändern. Was nicht so wirklich geht wenn Du da tatsächlich zeilenweise drüber iterierst, aber die Ausgabe wäre dann vielleicht das gewesen was Du am Ende in der Datei haben möchtest. Damit wäre das zumindest ein Schritt in die richtige Richtung gewesen.

Du bist halt sehr, äh, ökonomisch mit Informationen über das eigentliche Problem. M3U-Datei*en*, Mehrzahl? Wo kommen die denn jetzt her? Ist ~/quelle eine M3U-Datei? Oder ist das eine Datei wo auch Verzeichnispfade drin stehen und *da* sind dann M3U-Dateien drin? Welche Datei(en) soll(en) (inhaltlich?) geändert werden? Und wie? Und warum?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Eventuell geht es darum:

Wenn man sed (oder einem anderen Tool, das eine Datei zum Lesen erwartet) den Inhalt einer Variablen vorwerfen will, kann man das mit Here-Strings (vgl. https://www.gnu.org/software/bash/manual/bash.html#Here-Strings) machen:

1
sed -i "s,$,/*," <<< "$line"

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4695

Wohnort: Berlin

Da funktioniert a) das -i nicht, weil es hier keine Datei gibt die sed in-place bearbeiten könnte, und b) habe ich mit echo "$line/*" ja bereits einen deutlich einfacheren Weg gezeigt als sed zu starten um da einfach /* ans Ende anzuhängen.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

Marantkurz schrieb:

sed bringt wenn Bedingung erfüllt ist: "kann nicht bearbeitet werden: Das ist keine normale Datei". Verständlich, und ich weiss nicht weiter. Bitte um Hilfe.

while read line; do
	echo "zeile: $line"
	if [ -d $line ]; then sed -i "s,$,/*," $line;fi
done  <  ~/quelle

Meinst Du vielleicht

1
2
3
4
5
6
7
8
while read line
do
	echo "zeile: $line"
	if [ -d $line ]
        then 
            echo $line | sed "s,$,/*," 
         fi
done  <  ~/quelle

?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Marc_BlackJack_Rintsch schrieb:

Du müsstest wohl mal etwas weiter ausholen und beschreiben was Du da für Daten, Datei- und Verzeichnisnamen hast, und was Du erreichen möchtest, und vielleicht auch warum.

Genau. Was ist denn Sinn der Übung?

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 941

Das ist der Grund:

GUI(perYAD) Pfade an Player

https://forum.ubuntuusers.de/topic/gui-peryad-vermittlung-v-pfaden-an-auswahl-pla/

Hatte vor das darin zu verwursten. Momentan nicht nötig. Wollte dennoch wissen, wie das hinzubekommen sei. Werde mir die Vorschläge von @seahawk1986 und @user_unknown später ansehen.

Danke Euch!

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9785

Wohnort: Münster

Marantkurz schrieb:

[…]

1
2
3
4
while read line; do
	echo "zeile: $line"
	if [ -d $line ]; then sed -i "s,$,/*," $line;fi
done  <  ~/quelle

Leider ist unklar, was Du genau nachfragst. Ich vermute mal:

  • Du willst eine Textdatei bearbeiten.

  • In dieser Datei sollen Zeilen, welche einen Dateinamen eines Ordners enthalten, mit einem / enden; andere Zeilen sind unverändert zu übernehmen.

Textdateien gearbeitet man üblicherweise mit sed, da in Deinem Fall aber das Kriterium „ist ein Ordner“ nicht in der Datei vorhanden ist, sondern aus Metadaten der Datei folgt, geht das so nicht. Bash dagegen kann über Dateizeilen iterieren und andere Programme aufrufen, auch sed, aber sed kann natürlich nicht den Eingabestrom stdin ändern, schon gar nicht "in place" und die Datei, dessen Namen man hat, zu ändern, ist natürlich auch falsch, selbst wenn es kein Ordner wäre.

Dieses Bash-Schnipsel leistet das, was ich vermute (Ist allerdings ungetestet!):

1
2
3
4
while read line
do 	echo -n $line
 	test -d $line && echo / || echo
done  <  ~/quelle

sed benötigt man gar nicht. Natürlich muss ggf. noch die Ausgabe dieses Programms in eine neue Datei ("edit in place" geht nicht) umgeleitet werden, das überlasse ich Dir als Übungsaufgabe.

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 941

Ich berichte mal, getestet zumindest ergab das:

Ausführung ohne Fehler und auch ohne Erfolg.

@user_unknown Anhängen von /* im Terminal , in der m3u keine Änderung.

@kB Anhängen von / im Terminal , in der m3u keine Änderung.

Kann auch nicht nachvollziehen wie dann echo auf Zeile der txt Datei Auswirkung haben sollte.

shiro Team-Icon

Supporter

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1285

Hallo Marantkurz,

Die Antwort auf den Post von Marc_BlackJack_Rintsch hast du leider noch nicht geliefert. Aus diesem Grund vermute ich, dass du ein Verzeichnis in der .m3u mit einem "/*" abschließen willst (warum auch immer). Demnach würde mein Vorschlag wie folgt lauten:

$ # DIE QUELLE
$ cat test1.m3u
#EXTM3U
#EXTINF:,Joseph Haydn: String Quartet No.78 in B flat major Op.76 No.4 "Sunrise": Adagio
0-Musik/Joseph Haydn/String Quartets No 76, 77, 78/10-String Quartet No.78 in B flat major Op.76 No.4 _Sunrise__ Adagio.mp3
#EXTINF:,Johann Melchior Molter: Konzert fuer Floete, Streicher und Basso continuo G-Dur H.S. 315
0-Musik/Johann Melchior Molter
$ 
$ # DAS SCRIPT
$ cat test.sh
#/bin/bash
quelle=${1:-test1.m3u}
[ -e $$ ] && rm $$
while read line; do 
 if [ "${line:0:1}" == "#" ]; then
  echo "$line" >>$$
 else
  if [ -e "$line" ]; then 
   if [ -d "$line" ]; then 
    echo "DIRE:$line"
    echo "$line/*" >>$$
   else 
    echo "FILE:$line"
    echo "$line" >>$$
   fi
  else 
   echo "NoEX:$line"
  fi
 fi
done <$quelle
mv $quelle $quelle.sav
mv $$ $quelle
$ 
$ # DER TESTLAUF
$ . test.sh
FILE:0-Musik/Joseph Haydn/String Quartets No 76, 77, 78/10-String Quartet No.78 in B flat major Op.76 No.4 _Sunrise__ Adagio.mp3
DIRE:0-Musik/Johann Melchior Molter
$ 
$ # DER VERGLEICH
$ diff test1.m3u test1.m3u.sav 
5c5
< 0-Musik/Johann Melchior Molter/*
---
> 0-Musik/Johann Melchior Molter
$ 

Marantkurz

(Themenstarter)

Anmeldungsdatum:
7. September 2023

Beiträge: 941

Grrrrr ☺ Das Ding ist gefährlich. löscht, wenn man nicht aufpasst alles kurz und klein.

Im Ernst, es funktioniert, würde ich aber so nie einsetzen. Entschärft schon.

Zum Nachvollziehen, bestimmt nicht nur für mich:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#quelle=${1:-test1.m3u}				        #Bahnhof..
quelle=~/weit/weit/weg/keine.m3u
[ -e $$ ] && rm $$
while read line; do 
if [ "${line:0:1}" == "#" ]; then		        #line:0:1 ?
	echo "$line" >>$$			        #$pid
else
	if [ -e "$line" ]; then 
   		if [ -d "$line" ]; then 
    		     echo "DIRE:$line"			#
    		     echo "$line/*" >>$$
		     else 
    		     echo "FILE:$line"
		     echo "$line" >>$$
		fi
	else 
	echo "NoEX:$line"				#
	fi
fi
done <$quelle						#??
mv $quelle $quelle.					#??
mv $$ $quelle						#wieso?

Kannst Du bitte noch etwas Bedeutendes dazu kundtun? Habe ich extra schön formuliert. Übrigens: Guter Geschmack.

@Marc_BlackJack_Rintsch hatte ich doch mitgeteilt, daß die Quelle im Prinzip ne Textdatei ist. Eben mit Pfaden. Dachte ich zumindest.

Grund vermute ich, dass du ein Verzeichnis in der .m3u mit einem "/*" abschließen willst

Ja doch, das war mein heimlicher Wunsch. Schon immer gewesen. Hatte gerade Den laufen, daher die Gute Laune. Bin aber auch ein ganzes Stück ergriffen. Von Allem. 😉

Antworten |