ubuntuusers.de

Suchen und Ersetzen im String

Status: Ungelöst | Ubuntu-Version: Ubuntu 16.04 (Xenial Xerus)
Antworten |

foxiproxy

Anmeldungsdatum:
16. Oktober 2009

Beiträge: 227

Hallo zusammen,

seit über einer Stunde versuche ich nun schon, eine einfache Liste von Dateien in eine Variable zu schreiben und anschließend ein paar Zeichen zu ersetzen. Nachdem ich gefühlt jede Seite im Internet durchsucht habe, versuche ich jetzt hier mein Glück. Eigentlich dürfte die Aufgabe nicht schwer sein:

Ich benötige einen String in der Form Datei1.mp4|Datei2.mp4|Datei3.mp4

Die Dateien sammel ich im Ordner mit $(find -maxdepth 1 -iname '*.mp4') zusammen.

Daraus kommt dann ein String ./Datei1.mp4 ./Datei2.mp4 ./Datei3.mp4

Wie komme ich nun zu dem oben genannten String mit dem Pipes zwischen den Dateinamen? Ich bekomme es einfach nicht hin. Weder mit sed, noch mit tr, noch mit find direkt, mit oder ohne RegEx....

Ich bin ratlos und hoffe auf eine Lösung ☺

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

1
2
piped=$(find -maxdepth 1 -iname '*e.svg' -printf "|%f")
echo ${piped:1}

Alternativ:

1
2
pp=($(ls *e.svg*))
echo ${pp[@]} | sed 's/ /|/g' 

Beide Versionen sind gegenüber Leerzeichen in Dateinamen verwundbar, weswegen Leerzeichen u.ä. in Dateinamen keine gute Idee sind.

Man kann sich zwar zum Beispiel so behelfen:

1
2
piped=$(find -maxdepth 1 -iname '*e.svg' -printf "|'%f'")
echo ${piped:1}

Jetzt ist man das Problem mit Leerzeichen los und hat eins mit Apostrophen. ☺

Alternativ so:

1
echo ${pp[@]} | sed 's/ /"|"/g;s/^/"/;s/$/"/'

Wüssten wir, welches Ziel Du erreichen willst, nicht welche Methode Du testest, könnten wir vielleicht einen besseren Rat geben.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

foxiproxy schrieb:

Ich benötige einen String in der Form Datei1.mp4|Datei2.mp4|Datei3.mp4

Wozu?

noisefloor Team-Icon

Anmeldungsdatum:
6. Juni 2006

Beiträge: 29567

Hallo,

geht auch mit drei Zeilen Python 3:

1
2
3
4
5
>>> import os
>>> files = os.listdir()
>>> '|'.join(sorted(files))
"01-Sugar-Copper Blue-The Act We Act_128.mp3|02-Sugar-Copper Blue-A Good Idea_128.mp3|03-Sugar-Copper Blue-Changes_128.mp3|04-Sugar-Copper Blue-Helpless_128.mp3|05-Sugar-Copper Blue-Hoover Dam_128.mp3|06-Sugar-Copper Blue-The Slim_128.mp3|07-Sugar-Copper Blue-If I Can't Change Your Mind_128.mp3|08-Sugar-Copper Blue-Fortune Teller_128.mp3|09-Sugar-Copper Blue-Slick_128.mp3|10-Sugar-Copper Blue-Man on the Moon_128.mp3"
>>>

Es stellt sich hier aber in der Tat die Frage nach dem Sinn - warum will man so eine Darstellung haben? Wenn man an den Namen was ändern will ist es zumindest mit Python deutlich einfacher, über die Liste, die os.listdir() liefert, zu iterieren.

Gruß, noisefloor

foxiproxy

(Themenstarter)

Anmeldungsdatum:
16. Oktober 2009

Beiträge: 227

Bitte entschuldigt meine späte Antwort, hier nun die Begründung. Vielleicht gibt es ja auch eine einfachere Methode.

Ich würde gern mit ffmpeg ein paar einzelne MP4-Dateien zu einer zusammenfassen, und zwar mit dem Befehl

1
ffmpeg -i "concat:1.ts|2.ts|3.ts" -c copy out-clean.ts

Und genau DAFÜR benötige ich die Schreibweise mit den Pipes Schreibweise (hier 1.ts|2.ts|3.ts)

Gibt es eine bessere Methode als nach der, nach der ich oben gefragt habe? Bin für jede Antwort dankbar.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Wohnort: Göttingen

Also für das find-Kommando oben ginge es auch so:

find -maxdepth 1 -iname "*.mp4" -printf '%P|' | head -c-1

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Es gäbe auch noch

1
find -maxdepth 1 -iname '*.mp4' | paste -sd \|

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

foxiproxy schrieb:

Und genau DAFÜR benötige ich die Schreibweise mit den Pipes Schreibweise (hier 1.ts|2.ts|3.ts)

Gibt es eine bessere Methode als nach der, nach der ich oben gefragt habe? Bin für jede Antwort dankbar.

Es kommt darauf an, was man genau machen will - https://trac.ffmpeg.org/wiki/Concatenate listet einige Alternativen zu der Trennung der Dateien mit einem Pipe-Zeichen.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Auch wenn die Frage schon drei Wochen alt ist, noch ein Vorschlag dazu:

  1. Die Ausgabe von find erst (mit Leerzeichen) zwischenzuspeichern halte ich für eine unsichere Lösung. Das gibt Trouble, sobald da ein Leerzeichen oder sonstwas eigenartiges im Dateinamen vorkommt.

  2. Da Du sowieso nur 1 Verzeichnisebene abarbeiten willst, ist eine for-Schleife deutlich einfacher und klarer.
    Innerhalb der Schleife kannst Du direkt den String bauen, und ihn nachher noch passend nacharbeiten:
    (also den ersten "|" löschen, z.B. mit einer Parameter Expansion, und den Vorspann anfügen)

    track@track:~$ for f in test_i*; do
        text="$text|$f";
    done
    track@track:~$ echo  "$text"
    |test_ical|test_ip|test_ip2|test_ip3
    track@track:~$ echo  "concat:${text/|/}"
    concat:test_ical|test_ip|test_ip2|test_ip3 

    Statt echo wirst Du natürlich sinnigerweise direkt Deinen ffmpeg - Befehl einsetzen.

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

track schrieb:

  1. Die Ausgabe von find erst (mit Leerzeichen) zwischenzuspeichern halte ich für eine unsichere Lösung. Das gibt Trouble, sobald da ein Leerzeichen oder sonstwas eigenartiges im Dateinamen vorkommt.

Kann man im Falle meiner Lösung einfach beheben:

1
find -maxdepth 1 -iname '*.mp4' -print0 | paste -zsd \|

Aber es können natürlich immer noch Pipe-Zeichen in den Namen vorkommen... 😉

Antworten |