ubuntuusers.de

Script für Verzeichnis-Scan und Symlink gesucht

Status: Ungelöst | Ubuntu-Version: Ubuntu 24.10 (Oracular Oriole)
Antworten |

FRauANtje

Anmeldungsdatum:
5. März 2025

Beiträge: 5

Moin,

ich suche ein Script, welches innerhalb eines Verzeichnisbaums nach Dateitypen sucht (z.B. mkv, avi und mp4) und die 10 oder 15 neuesten als Symlink von einem anderen Verzeichnis (z.B. "neues") verlinkt.

"Neuste" wenn möglich nicht via Timestamp sondern via Erstellungs- oder Änderungsdatum ermitteln.

Es können auch Umlaute oder Spaces in den Dateinamen vorkommen.

Mit meinen eigenen Versuchen bin ich leider kollossal gescheitert ☹

Liebe Gruesse und Danke vorab!

F

micneu

Avatar von micneu

Anmeldungsdatum:
19. Januar 2021

Beiträge: 705

Wohnort: Hamburg

Schreib dir doch ein Script, das sollte nicht so aufwendig sein

  • poste mal deinen code, darauf können wir dann aufbauen

Mylin

Avatar von Mylin

Anmeldungsdatum:
23. Juli 2024

Beiträge: 230

Oder, wieviel darf denn dieses Script kosten? Und, die Lizensfrage sollte geklärt werden.

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 241

Wohnort: Aachen

Moin,

FRauANtje schrieb:

Mit meinen eigenen Versuchen bin ich leider kollossal gescheitert ☹

etwa so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

# Hauptordner der Suche
root="/media/daten"

# Werte nur bei Zeilenumbrüchen trennen
IFS=$'\n'

# Für neusten 10 Videos
for vid in $(find "$root" -type f \( -iname "*.mkv" -or -iname "*.mp4 -or "*.avi" \) printf "%CF %CT;%p\n" | sort -r | head -n10 | cut -d';' -f2);do
  # Verknüpfe hier $vid wohin auch immer. Beispiel:
  #ln -sf "$vid" "$HOME/Videos/"
done

Gruß Thomas

micneu

Avatar von micneu

Anmeldungsdatum:
19. Januar 2021

Beiträge: 705

Wohnort: Hamburg

Ich bin heute mal nett, meine Variante als Einzeiler (nicht getestet)

find /pfad/zum/quellverzeichnis -type f \( -name "*.mkv" -o -name "*.avi" -o -name "*.mp4" \) -printf '%T@ %p\n' | sort -nr | head -n 15 | while IFS= read -r line; do file="${line#* }"; ln -sf "$file" "/pfad/zum/zielverzeichnis/$(basename "$file")"; done

FRauANtje

(Themenstarter)

Anmeldungsdatum:
5. März 2025

Beiträge: 5

Erstmal vielen Dank!! Da kommt der "neue" und fragt gleich nach einem fertigen Script... Insofern verstehe ich auch die etwas ironischen Reaktionen hier 😉

Meine eigenen Fähigkeiten sind vorhanden aber begrenzt. Bevor ich mich hier angemeldet habe, hab ich schon länger und öfter mal nach einem Gerüst gesucht, um es für mich zurecht zu basteln. Das hat früher in einigen Fällen auch funktioniert. Nun kam ich aber nicht wirklich weiter.

Besten Dank für die Hilfe bis hierher - ich werde mal schauen, ob ich damit das hinbekomme, was ich mir vorstelle und mich auf jeden Fall zurück melden!

LG

F

PS: Ich sehe gerade "Ich gebe keine Schlüssellösung, ich gebe Hinweise wie das Problem gelöst werden kann (sonst lernst du ja nichts)" ☺ Genau so sollte das sein, ich hab mich nur nicht getraut, meinen gescheiterten und total unästetischen Versuch hier bei der Frage mit einzustellen. War mir zu peinlich. Mach ich aber nächstes Mal ☺

FRauANtje

(Themenstarter)

Anmeldungsdatum:
5. März 2025

Beiträge: 5

@TK87 Heissen Dank nochmal. Ich bekomme allerdings Fehlermeldungen. Muss vor das "*.avi" nicht auch noch ein -iname ?

@micneu Dein Einzeiler funktioniert suepr und sauschnell. Damit ich was lerne, versuche ich mal zu verstehen, wie das geht. Danke! Den kann ich mir bestimmt im mc editor etwas strukturieren - der hilft ja bei der syntax etwas durch einfärben...

Sorry Cracks, ich bin eben ein Dummy, aber ich versuche zu lernen.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

FRauANtje schrieb:

@TK87 Heissen Dank nochmal. Ich bekomme allerdings Fehlermeldungen. Muss vor das "*.avi" nicht auch noch ein -iname ?

Ja.

Sorry Cracks, ich bin eben ein Dummy, aber ich versuche zu lernen.

Willkommen hier im Forum!

Weil ich gerade Urlaub habe und schon länger nix mehr in Ruby geschrieben habe, hier noch eine Variante in dieser Skript-Sprache. Ich finde es generell recht lesbar (bis auf die Regex vermutlich). Lass mal wissen, wie es Dir damit geht, falls Du Lust hast, das auch noch verstehen zu wollen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/ruby

# Create symlinks for the most recent N videos

base_dir = '/home/antje/data'
news_dir = '/home/antje/news'
items = 15

require 'find'

videos = []

Find.find base_dir do |f|
  if /\.(mkv|avi|mp4)$/i =~ f && File.file?(f)
    videos << f
  end
end

videos.sort_by! {|f| File.stat(f).mtime}

# if too long use truncated array, else original
(videos.slice!(-items..-1) or videos).each do |f|
  File.symlink(f, news_dir + '/' + File.basename(f)) rescue nil
end

Die Variablen mit den Pfaden musst Du natürlich nach Deinen Bedürfnissen setzen. Zum Nachschlagen der Klassen Module und Funktionen empfiehlt sich ruby-doc.org.

FRauANtje

(Themenstarter)

Anmeldungsdatum:
5. März 2025

Beiträge: 5

@rklm : Danke! Ich kannte ruby noch garnicht, obwohl das auf meinem Rechner offenbar bereits installiert ist. Das schau ich mir nachher mal an. Dümmer macht mich das sicher nicht ☺

Ich melde mich auf jeden fall zurück!

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

Alternative in Python (ungetestet):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python3
from heapq import nlargest
from pathlib import Path

USER_PATH = Path.home()
VIDEOS_PATH = USER_PATH / "data"
NEW_VIDEOS_PATH = USER_PATH / "news"
ITEM_COUNT = 15


def main():
    suffixes = {".mkv", ".avi", ".mp4"}
    for file_path in nlargest(
        ITEM_COUNT,
        (
            path
            for path in VIDEOS_PATH.rglob("*")
            if path.is_file() and path.suffix.lower() in suffixes
        ),
        lambda path: path.stat().st_mtime,
    ):
        (NEW_VIDEOS_PATH / file_path.name).symlink_to(file_path)


if __name__ == "__main__":
    main()

FRauANtje

(Themenstarter)

Anmeldungsdatum:
5. März 2025

Beiträge: 5

Marc_BlackJack_Rintsch schrieb:

Alternative in Python (ungetestet):

Wow, danke! Aber das kann ich mir erst genauer anschauen, wenn ich die anderen Scripte so halbwegs verstanden habe 😉 Aber auch hier werde ich mich zurückmelden! Und wenn es mir grad nicht hilft, dann vllt. jemand anderem, der das hier liest.

Ich vesuche mich aktuell grad an dem Einzeiler von micneu (danke nochmal!).

Nach dem Studium von manpage find habe ich versucht, durch den Parameter -ctime -5 die Suche auf alle Dateien einzuschränken, die 5 Tage oder jünger sind (unabhängig vom Timestamp der Datei und vom letzten lesenden Zugriff (daher kein -atime)).

Wenn ich es richtig verstanden habe, müsste das hier mit eingefügt werden: -type f \( -name "*.mkv" -o -name "*.avi" -o -name "*.mp4" \). Das erzielt aber nicht die gewünschte Wirkung. Kommt das durch die -o(der) konstruktionen in den Klammern? Muss ich das dann zu jedem Dateityp mit -a(and) dazuschreiben oder Klammern setzen?

vmp

Anmeldungsdatum:
28. März 2018

Beiträge: 130

Um in Dateien (z.B. *.txt) nach bestimmten "text_ausdruck" zu suchen habe ich mir mal folgendes aufgeschrieben:

find . -name '*.txt' -type f -exec grep -q text_ausdruck {} \; -print

um nach bestimmten Dateien (z.B. *.mp4) zu suchen:

find . -name '*.mp4' -type f -print

falls man zusätzliche Optionen benötigt im Terminal

man find

eintippen.

Antworten |