ubuntuusers.de

dateien rekursiv suchen und verschieben

Status: Ungelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

Sebastian_S

Avatar von Sebastian_S

Anmeldungsdatum:
2. Mai 2006

Beiträge: 215

Wohnort: Oberursel

Hallo zusammen,

ich hab noch so einige videos von meiner Digitalkammerea in meinem ~/Bilder Verzeichnis.

Wie kann ich alle Videodateien (MOV) in allen Unterverzeichnissen suchen und dann nach ~/Videos verschieben?

Also

1
~/Bilder/2005/06/geburtstag/video01.mov

nach

1
~/Videos/2005/06/geburtstag/video01.mov

verschieben?

Danke,

Seb

agschaal

Anmeldungsdatum:
13. August 2009

Beiträge: 680

Wohnort: Berlin

Am besten mit find

So entfernt man beispielsweise Ümlaute von der Datenplatte:

find / -name "*Ü*" -exec rename 's/Ü/Ue/g' "{}" \;

Bei dir wird das wahrscheinlich:

find ./ -name "*.mov" -exec mv /daten/hier gehören meine videos hin \;

aber schau noch mal im manuel nach, eventuell habe ich dein Problem nicht richtig erfast.

Andre

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Normalerweise nimmt man ja für sowas einfach nur find ... -exec ... {} \; und fertig.
Das Problem ist hier nur, dass man bei dem {} keine Parameter Expansion benutzen kann.

Aber das ist lösbar, siehe z.B. auf http://forum.chip.de/linux/dateien-unterordnern-umbenennen-700916.html .
Man muss allerdings vorher ggf. noch das Zielverzeichnis erzeugen, und dafür braucht man eine doppelte Parameter Expansion:

find Bilder -type f -name '*.MOV' -exec  sh -c 'ziel="Videos/${0#Bilder/}"; mkdir -p "${ziel%/*}"; mv "$0" "$ziel"' {} \;

Dieser Weg über die Untershell erlaubt dann doch wieder die Parameter Expansion.

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13216

Hiho,

Sebastian_S schrieb:

Also

1
~/Bilder/2005/06/geburtstag/video01.mov

nach

1
~/Videos/2005/06/geburtstag/video01.mov

verschieben?

So ungefähr könnt's auch gehen:

1
2
3
4
target=~/Videos
mkdir -p "$target" \
&& ( cd ~/Bilder \
     && find . -type f -iname '*.mov' -exec cp -a --parents -t "$target" {} + -exec rm {} + )

Unschön ist, dass man erst kopiert und dann löscht. mv hat allerdings keine Option --parents. Man kann den temporären Platz etwas reduzieren, indem man die Befehle einzeln pro Datei ausführen lässt:

1
2
3
4
target=~/Videos
mkdir -p "$target" \
&& ( cd ~/Bilder \
     && find . -type f -iname '*.mov' -exec cp -a --parents -t "$target" {} \; -exec rm {} \; )

Und Vorsicht: erst testen!

Ciao

robert

Sebastian_S

(Themenstarter)
Avatar von Sebastian_S

Anmeldungsdatum:
2. Mai 2006

Beiträge: 215

Wohnort: Oberursel

hui hier gehts ja ab. Mein Wissen im terminal ist doch sehr beschaulich.

rklm schrieb:

Unschön ist, dass man erst kopiert und dann löscht. mv hat allerdings keine Option --parents. Man kann den temporären Platz etwas reduzieren, indem man die Befehle einzeln pro Datei ausführen lässt:

An 'Bilder' komplett kopieren und dann löschen hab ich auch schon gedacht. Sind aber 35GB :-/

So jetzt werde ich mich mal ans ausprobieren machen

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Sebastian_S schrieb:

An 'Bilder' komplett kopieren und dann löschen hab ich auch schon gedacht. Sind aber 35GB :-/

Ist bei der Datenmenge wirklich Quatsch, weil dann natürlich die ganzen 35 GB bewegt werden müssten.
Das liefert neben dem Aufwand auch eine unnütze Fragmentierung oder zumindest Verteilung der Daten.
(was im Endeffekt den Zugriff auf diese Daten im Laufe der Zeit träger macht !)

Beim Umbenennen (= mv auf der selben Partition) werden tatsächlich nur die Verzeichniseinträge geändert.
Deshalb habe ich diesen Weg genommen, da gibt es diese Nachteile nicht.

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13216

track schrieb:

Sebastian_S schrieb:

An 'Bilder' komplett kopieren und dann löschen hab ich auch schon gedacht. Sind aber 35GB :-/

Ist bei der Datenmenge wirklich Quatsch, weil dann natürlich die ganzen 35 GB bewegt werden müssten.

Alles wird von meinem Skript ja nicht kopiert, das wäre wirklich totaler Schwachsinn.

Das liefert neben dem Aufwand auch eine unnütze Fragmentierung oder zumindest Verteilung der Daten.
(was im Endeffekt den Zugriff auf diese Daten im Laufe der Zeit träger macht !)

Das hängt davon ab, wie viel Platz im Filesystem ist. Das Kopieren kann die Fragmentierung tatsächlich sogar verringern.

Beim Umbenennen (= mv auf der selben Partition) werden tatsächlich nur die Verzeichniseinträge geändert.
Deshalb habe ich diesen Weg genommen, da gibt es diese Nachteile nicht.

Ja, das ist auf jeden Fall zu bevorzugen. Wenn ich etwas Zeit und Muße habe, schreibe ich mal ein kleines Skript, das mv eine --parents Option verpasst. Das kann man dann schön mit find verwenden.

Ciao

robert

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13216

rklm schrieb:

Ja, das ist auf jeden Fall zu bevorzugen. Wenn ich etwas Zeit und Muße habe, schreibe ich mal ein kleines Skript, das mv eine --parents Option verpasst. Das kann man dann schön mit find verwenden.

So, hier isses:

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/bin/dash

# Mv which can move subtrees

test -n "$DEBUG" && set -x

# functions
help() {
cat <<HELP

Move directory trees.

Usage: $0 options file names...

Options:

 -c <name>	Cut leading portion of path.
 -t <name>	Target directory to move to.
 -v		Verbose output from moving.
 -h		This help.

HELP
}

# option processing

target='.'
verbose=

while getopts ':c:t:vh' opt; do
	case "$opt" in
	c)	# cut base path
		base="$OPTARG"
		;;
	t)	# target dir
		target="$OPTARG"
		;;
	v)	# verbose output
		verbose='-v'
		;;
	h)	# help
		help
		exit 0
		;;
	*)	# unknown
		echo "ERROR: unknown option $OPTARG" >&2
		exit 1
	esac
done

shift $((OPTIND - 1))

test -d "$target" || { echo "ERROR: not a directory: $target" >&2; exit 1; }

# main

for f; do
  # cut off leading portion
  p="${f#$base}"
  # get path component
  d=$(dirname "$p")
  mkdir -p "$target/$d" && mv $verbose "$f" "$target/$d"
done

Damit müsste es so gehen

1
$ find ~/Bilder -type f -iname '*.mov' -exec mv-tree.sh -c ~/Bilder/ -t ~/Videos {} +

Ciao

robert

Sebastian_S

(Themenstarter)
Avatar von Sebastian_S

Anmeldungsdatum:
2. Mai 2006

Beiträge: 215

Wohnort: Oberursel

Hi track,

das hat ja wunderbar funktioniert! Danke.

track schrieb:

find Bilder -type f -name '*.MOV' -exec  sh -c 'ziel="Videos/${0#Bilder/}"; mkdir -p "${ziel%/*}"; mv "$0" "$ziel"' {} \;

Ich kann sogar den Befehl lesen und nachvollziehen was da gemacht wird. Ich sollte definitiv mehr im Terminal sein.

Die Andere Möglichkeit habe ich nicht versucht... aber nur weil ich das in eine weitere Datei kopieren hätte müssen. 🙄

rklm schrieb:

Damit müsste es so gehen

1
$ find ~/Bilder -type f -iname '*.mov' -exec mv-tree.sh -c ~/Bilder/ -t ~/Videos {} +

Ciao

robert

Super arbeit... beide Ansätze haben genau das gemacht, was ich gesucht habe!

Danke

prov

Anmeldungsdatum:
21. Dezember 2009

Beiträge: Zähle...

Hi, ich habe eine ähnliche Problemstellung, komme aber mit den angegebenen Lösungen nicht weiter.

Meine Problemstellung: Ich habe ein Verzeichnis (z.B. Ordner "1-199") mit Unterverzeichnissen, aus denen ich bestimmte Dateitypen, z.B. PDFs in einen anderen Ordner verschieben möchte.

1-199
- (diverse Unterordner)
-- PDFs

diese PDFs sollen nun in einen Ordner "wichtig" auf Höhe des Ordners "1-199" verschoben werden. Mit den angebotenen Lösung:

find /1-199 -type f -iname '*.pdf' -exec mv-tree.sh -c /1-199/ -t /wichtig {} +

bekomm ich die Antwort:

find: "/1-199": Datei oder Verzeichnis nicht gefunden

Bei

find 1-199 -type f -name '*.pdf' -exec sh -c 'ziel="wichtig/${0#1-199/}"; mkdir -p "${ziel%/*}"; mv "$0" "$ziel"' {} \;

bekomme ich gar keine Rückmeldung.

Was mache ich denn falsch?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13216

prov schrieb:

Was mache ich denn falsch?

Du gibst Slashes zu viel an.

find /1-199 -type f -iname '*.pdf' -exec mv-tree.sh -c /1-199/ -t /wichtig {} +

Ciao

robert

Antworten |