Da Unix und Linux nicht , zu einer großen Website über seine Werkzeuge haben, so einfach ich Webseite gehen , wie about.comund eine andere Website für die Liste der Optionen zur Verfügung , die ich möglicherweise .. verwenden kann , aber nichts gefunden wietail
Gaijin
Antworten:
37
for file in $(ls -p | grep -v / | tail -100)
do
mv $file /other/location
done
Das setzt voraus , Dateinamen enthalten keine Leerzeichen, Zeilenumbruch (vorausgesetzt , der Standardwert $IFS), Wildcard - Zeichen ( ?, *, [) oder beginnen mit -.
Beachten Sie, dass dieser Ansatz nur funktioniert, wenn die Dateinamen keine Sonderzeichen (Leerzeichen, nicht druckbare Zeichen, ``) enthalten. Analysieren Sie in derls Regel nicht die Ausgabe von . Und immer doppelte Anführungszeichen für Parameter und Befehle.
Gilles 'SO- hör auf böse zu sein'
1
Welcher Teil macht 100 Dateien aus?
Tshepang
3
Aktualisierung meines vorherigen Kommentars: Nachdem ich Gilles 'Referenzlink gelesen habe, analysiere nicht die Ausgabe von ls . Ich habe festgestellt, dass mein findBefehl fehlte. Ein Argument befand sich an der falschen Stelle und ich habe Null-Dateinamen-Endungen hinzugefügt. Es ist ein bisschen lang, aber das ist alles, was ich in einem Kommentar tun kann. Hier ist der feste Ausschnitt:find . -maxdepth 1 -type f \( ! -iname ".*" \) -print0 | while read -rd $'\0' file ; do mv -- "$file" /other/location/ ; done
Peter.O
@perer Nur als Hinweis, dass die read -dOption nicht auf alle Shells übertragbar ist, aber wenn Sie bashsowieso verwenden, -d ''sollten Sie den gleichen Effekt erzielen wie -d $'\0'.
JW013
FWIW Wenn Sie möchten, dass dies als Oneliner ausgeführt wird, fügen Sie eine Stelle ;hinzu, an der sich jetzt jede neue Zeile befindet.
Patrick
37
In zsh ist es am einfachsten:
mv -- *([1,100]) /other/location/
Dies bewegt die ersten 100 nicht versteckte Dateien (jeglicher Art, zu ändern , ([1,100])um (.[1,100])für regelmäßige Dateien nur, oder (^/[1,100])für jede Art aber Verzeichnis ) in Namen lexicographic Reihenfolge. Sie können mit dem oGlob-Qualifier eine andere Sortierreihenfolge auswählen , um z. B. die 100 ältesten Dateien zu verschieben:
mv -- *(Om[1,100]) /other/location/
Bei anderen Shells können Sie dies in einer Schleife mit einem frühen Ende tun.
i=0
for x in *; do
if [ "$i" = 100 ]; then break; fi
mv -- "$x" /other/location/
i=$((i+1))
done
+1 für sichere Shell-Erweiterung. Wäre mit der Inkrementoperation auch besser lesbar $(( i++ ))oder $[ i++ ]?
2
@hesse Einige Shells implementieren ++und nicht --. Sie können : $((i+=1))anstelle von schreiben i=$((i+1)); Ich bin nicht davon überzeugt, dass es besser lesbar ist.
Gilles 'SO - hör auf böse zu sein'
1
:-D, ich habe diese Antwort tatsächlich bearbeitet, weil ich dachte, es wäre meine ... Entschuldigung. Fühlen Sie sich frei, zurückzukehren, da dies die Bedeutung ändert.
Stéphane Chazelas
@ StéphaneChazelas Ich frage mich, warum Sie Verzeichnisse und Symlinks ausschließen würden, die Frage sagte nichts darüber.
Gilles 'SO - hör auf böse zu sein'
@ Gilles, die akzeptierte Antwort hat ls -p | grep -v /so die aktuelle Frage, die hier verdummt.
@phk, das würde funktionieren, zshauch wenn die zshSyntax auf den ersten Blick ziemlich fremd aussieht . Gilles hat einen viel einfacheren Weg gezeigt, dies zu tun zsh. Auch dann ist das noch zuverlässiger als die aktuell akzeptierte Antwort.
Stéphane Chazelas
3
Folgendes hat bei mir funktioniert. Es tut mir leid, wenn es zuvor gepostet wurde, aber ich habe es bei einem schnellen Scan nicht gesehen.
ls path/to/dir/containing/files/* | head -100 | xargs -I{} cp {} /Path/to/new/dir
mmv ist ein hervorragendes Dienstprogramm, mit dem Sie auch Dateien massenweise umbenennen können. (Ich musste es sudo apt-get install mmvauf meinem Computer installieren.) Einfaches Verwendungsbeispiel: Angenommen, Sie haben ein Dateiverzeichnis mit der Erweiterung .JPG, das Sie in Kleinbuchstaben (.jpg) ändern möchten. Der folgende Befehl macht den Trick:
mmv \*.JPG \#1.jpg
Der Backslash wird verwendet, um anzuzeigen, dass ein Platzhalter angezeigt wird. Das * / JPG stimmt mit nichts mit einer JPG-Erweiterung überein. Im Abschnitt "to" des Befehls verwendet die Nummer 1 den übereinstimmenden Text aus dem ersten Platzhalter, um die Datei umzubenennen. Natürlich können Sie der Nr. 1 einen anderen Pfad voranstellen, um auch die Datei zu verschieben.
Es wäre vorteilhafter, wenn Sie angeben würden, wie Sie das von Ihnen vorgeschlagene Tool tatsächlich verwenden würden, um das Ziel zu erreichen.
Dason
1
hat ein Verwendungsbeispiel hinzugefügt
Pete
1
#!/bin/bash
c=1; d=1; mkdir -p NEWDIR_${d}
for jpg_file in *.jpg
do
if [ $c -eq 100 ]
then
d=$(( d + 1 )); c=0; mkdir -p NEWDIR_${d}
fi
mv "$jpg_file" NEWDIR_${d}/
c=$(( c + 1 ))
done
Dies ist falsch, Sie übergeben drei Argumente an mv, von denen das letzte (wahrscheinlich) kein Verzeichnis ist. Und es beantwortet die Frage nicht wirklich - der Fragesteller möchte eine bestimmte Anzahl von Dateien verschieben, nicht alle.
Mat
Befehl aktualisiert.
Saumil
0
Ich kam hier vorbei, aber ich musste Dateien in Teilen (jeweils 99) von /DIR1nach kopieren /DIR2. Ich werde das Skript hier einfügen, um anderen zu helfen, vielleicht:
#!/bin/bash
# Thanks to <Jordan_U> @ #ubuntu
# 06 Dec 2014
i=0
copy_unit=98
for file in /DIR1/*; do
cp "$file" /DIR2
if [[ "$i" -ge "$copy_unit" ]]; then
echo "Pausing, press enter to continue"
read
i=0
fi
((i++))
done
Wenn Sie sicher sein möchten / Dateinamen mit Leerzeichen, Zeilenumbrüchen, Anführungszeichen, Backslashes usw. behandeln möchten, müssen Sie durch Null abgeschlossene Trennzeichen verwenden:
EDIT2: HINWEIS: Wenn Sie nicht haben head -z( aus irgendeinem Grund ) Sie können das ersetzen oben head -z -n 1000mit tr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'(oder andere Art und Weise sehen )
-maxdepth 1Es wird vermieden, in Unterverzeichnissen von nach Dateien zu suchen. $srcdirDie einzigen aufgelisteten sind die Dateien in $srcdir. -print0wird \0anstelle von newline ( \n) zwischen den einzelnen aufgelisteten Dateien verwendet - dies hilft bei der Behandlung von Dateien mit Zeilenumbrüchen und Leerzeichen mit xargs. head -zwerden \0terminierte (statt newline ( \n) terminierte) Zeilen als Zeilen gezählt. -n 100listet nur die ersten gefundenen 100Dateien findauf.
Wenn Sie sehen möchten, welcher Befehl ausgeführt xargswird, fügen Sie -t(oder --verbose) hinzu. xargs -0"Eingabeelemente werden durch ein Nullzeichen ( \0) anstelle von Leerzeichen abgeschlossen, und die Anführungszeichen und der Backslash sind keine besonderen Zeichen (jedes Zeichen wird wörtlich genommen)" xargs -rwerden nicht ausgeführtmvwenn keine zu verschiebenden Dateien vorhanden sind (dh wenn findkeine Dateien gefunden wurden). --Beendet die Verarbeitung von Argumenten als Optionen für das Programm. Weitere Informationen finden Sie hier
Beispielausgabe (führt einen mvBefehl aus und kann auch Dateien mit Zeilenumbrüchen im Namen verarbeiten):
$ find /tmp/t -maxdepth 1 -type f -print0 | head -z -n 100 | xargs -t -0 -r -- mv -t /tmp -- ; echo "exit codes: ${PIPESTATUS[@]}"
mv -t /tmp -- /tmp/t/file containing quotes"' then spaces /tmp/t/file containing quotes"' /tmp/t/file containing a slash n here\n /tmp/t/file containing a new line here
and continues /tmp/t/s /tmp/t/-x and -L 1. /tmp/t/of replace-str in the initi /tmp/t/-thisfile_starts_with_a_hyphen and has spaces and a -hyphen here /tmp/t/-thisfile_starts_with_a_hyphen and has spaces /tmp/t/-thisfile_starts_with_a_hyphen /tmp/t/another with spaces /tmp/t/one with spaces /tmp/t/c /tmp/t/a
exit codes: 0 0 0
$ ls -1R /tmp/t
/tmp/t:
a
'another with spaces'
b
c
'file containing a new line here'$'\n''and continues'
'file containing a slash n here\n'
'file containing quotes"'\'''
'file containing quotes"'\'' then spaces'
'of replace-str in the initi'
'one with spaces'
s
'some dir'
-thisfile_starts_with_a_hyphen
'-thisfile_starts_with_a_hyphen and has spaces'
'-thisfile_starts_with_a_hyphen and has spaces and a -hyphen here'
'-x and -L 1.'
/tmp/t/b:
'file with spaces'
'/tmp/t/some dir':
'some file'
Für find:
-maxdepth levels
Descend at most levels (a non-negative integer) levels of direc‐
tories below the starting-points. -maxdepth 0
means only apply the tests and actions to the starting-points
themselves.
-type c
File is of type c:
b block (buffered) special
c character (unbuffered) special
d directory
p named pipe (FIFO)
f regular file
l symbolic link; this is never true if the -L option or the
-follow option is in effect, unless the symbolic link is
broken. If you want to search for symbolic links when -L
is in effect, use -xtype.
s socket
D door (Solaris)
-P Never follow symbolic links. This is the default behaviour.
When find examines or prints information a file, and the file is
a symbolic link, the information used shall be taken from the
properties of the symbolic link itself.
-L Follow symbolic links. When find examines or prints information
about files, the information used shall be taken from the prop‐
erties of the file to which the link points, not from the link
itself (unless it is a broken symbolic link or find is unable to
examine the file to which the link points). Use of this option
implies -noleaf. If you later use the -P option, -noleaf will
still be in effect. If -L is in effect and find discovers a
symbolic link to a subdirectory during its search, the subdirec‐
tory pointed to by the symbolic link will be searched.
When the -L option is in effect, the -type predicate will always
match against the type of the file that a symbolic link points
to rather than the link itself (unless the symbolic link is bro‐
ken). Actions that can cause symbolic links to become broken
while find is executing (for example -delete) can give rise to
confusing behaviour. Using -L causes the -lname and -ilname
predicates always to return false.
Für head:
-n, --lines=[-]NUM
print the first NUM lines instead of the first 10; with the
leading '-', print all but the last NUM lines of each file
-z, --zero-terminated
line delimiter is NUL, not newline
BEARBEITEN: Jemand erwähnte, dass er keine head -zhatte. Dies ist die Version, die ich verwendet habe (in Fedora 25):
$ head --version
head (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie and Jim Meyering.
$ rpm -qf /usr/bin/head
coreutils-8.25-17.fc25.x86_64
Für xargs:
-0, --null
Input items are terminated by a null character instead of by
whitespace, and the quotes and backslash are not special (every
character is taken literally). Disables the end of file string,
which is treated like any other argument. Useful when input
items might contain white space, quote marks, or backslashes.
The GNU find -print0 option produces input suitable for this
mode.
-r, --no-run-if-empty
If the standard input does not contain any nonblanks, do not run
the command. Normally, the command is run once even if there is
no input. This option is a GNU extension.
-P max-procs, --max-procs=max-procs
Run up to max-procs processes at a time; the default is 1. If
max-procs is 0, xargs will run as many processes as possible at
a time. Use the -n option or the -L option with -P; otherwise
chances are that only one exec will be done. While xargs is
running, you can send its process a SIGUSR1 signal to increase
the number of commands to run simultaneously, or a SIGUSR2 to
decrease the number. You cannot increase it above an implemen‐
tation-defined limit (which is shown with --show-limits). You
cannot decrease it below 1. xargs never terminates its com‐
mands; when asked to decrease, it merely waits for more than one
existing command to terminate before starting another.
Please note that it is up to the called processes to properly
manage parallel access to shared resources. For example, if
more than one of them tries to print to stdout, the ouptut will
be produced in an indeterminate order (and very likely mixed up)
unless the processes collaborate in some way to prevent this.
Using some kind of locking scheme is one way to prevent such
problems. In general, using a locking scheme will help ensure
correct output but reduce performance. If you don't want to
tolerate the performance difference, simply arrange for each
process to produce a separate output file (or otherwise use sep‐
arate resources).
-t, --verbose
Print the command line on the standard error output before exe‐
cuting it.
Für cp:
-t, --target-directory=DIRECTORY
copy all SOURCE arguments into DIRECTORY
-v, --verbose
explain what is being done
Ich weiß, dass dieser Thread ziemlich alt ist, aber ich fand die Antworten komplizierter, als ich dachte, dass sie sein sollten. Dies funktionierte in CentOS, aber es scheint einfach genug, dass es wahrscheinlich in anderen Distributionen funktionieren sollte.
Dies funktioniert nicht, da die Ausgabe von lsnicht das führende somedir/Präfix enthält und nicht für Dateinamen mit Leerzeichen oder Platzhalterzeichen funktioniert oder mit beginnt -.
Stéphane Chazelas
Fair genug. Ich habe tatsächlich cp ls | head -n 100../someDir100/ aus dem Zielverzeichnis und keiner der Dateinamen erfüllt diese Fälle. Besser glücklich zu sein als gut!
about.com
und eine andere Website für die Liste der Optionen zur Verfügung , die ich möglicherweise .. verwenden kann , aber nichts gefunden wietail
Antworten:
Das setzt voraus , Dateinamen enthalten keine Leerzeichen, Zeilenumbruch (vorausgesetzt , der Standardwert
$IFS
), Wildcard - Zeichen (?
,*
,[
) oder beginnen mit-
.quelle
ls
Regel nicht die Ausgabe von . Und immer doppelte Anführungszeichen für Parameter und Befehle.find
Befehl fehlte. Ein Argument befand sich an der falschen Stelle und ich habe Null-Dateinamen-Endungen hinzugefügt. Es ist ein bisschen lang, aber das ist alles, was ich in einem Kommentar tun kann. Hier ist der feste Ausschnitt:find . -maxdepth 1 -type f \( ! -iname ".*" \) -print0 | while read -rd $'\0' file ; do mv -- "$file" /other/location/ ; done
read -d
Option nicht auf alle Shells übertragbar ist, aber wenn Siebash
sowieso verwenden,-d ''
sollten Sie den gleichen Effekt erzielen wie-d $'\0'
.;
hinzu, an der sich jetzt jede neue Zeile befindet.In zsh ist es am einfachsten:
Dies bewegt die ersten 100 nicht versteckte Dateien (jeglicher Art, zu ändern ,
([1,100])
um(.[1,100])
für regelmäßige Dateien nur, oder(^/[1,100])
für jede Art aber Verzeichnis ) in Namen lexicographic Reihenfolge. Sie können mit demo
Glob-Qualifier eine andere Sortierreihenfolge auswählen , um z. B. die 100 ältesten Dateien zu verschieben:Bei anderen Shells können Sie dies in einer Schleife mit einem frühen Ende tun.
Eine andere tragbare Möglichkeit wäre , die Liste der Dateien zu erstellen und alle bis auf die letzten 100 zu entfernen .
quelle
$(( i++ ))
oder$[ i++ ]
?++
und nicht--
. Sie können: $((i+=1))
anstelle von schreibeni=$((i+1))
; Ich bin nicht davon überzeugt, dass es besser lesbar ist.ls -p | grep -v /
so die aktuelle Frage, die hier verdummt.Wenn Sie zsh nicht verwenden:
Würde die letzten 100 (in alphabetischer Reihenfolge) verschieben.
quelle
Der folgende Oneliner in der Shell würde helfen.
quelle
zsh
auch wenn diezsh
Syntax auf den ersten Blick ziemlich fremd aussieht . Gilles hat einen viel einfacheren Weg gezeigt, dies zu tunzsh
. Auch dann ist das noch zuverlässiger als die aktuell akzeptierte Antwort.Folgendes hat bei mir funktioniert. Es tut mir leid, wenn es zuvor gepostet wurde, aber ich habe es bei einem schnellen Scan nicht gesehen.
quelle
Von https://stackoverflow.com/questions/14033129/how-to-move-a-given-number-of-random-files-on-unix-linux-os
quelle
mmv ist ein hervorragendes Dienstprogramm, mit dem Sie auch Dateien massenweise umbenennen können. (Ich musste es
sudo apt-get install mmv
auf meinem Computer installieren.) Einfaches Verwendungsbeispiel: Angenommen, Sie haben ein Dateiverzeichnis mit der Erweiterung .JPG, das Sie in Kleinbuchstaben (.jpg) ändern möchten. Der folgende Befehl macht den Trick:Der Backslash wird verwendet, um anzuzeigen, dass ein Platzhalter angezeigt wird. Das * / JPG stimmt mit nichts mit einer JPG-Erweiterung überein. Im Abschnitt "to" des Befehls verwendet die Nummer 1 den übereinstimmenden Text aus dem ersten Platzhalter, um die Datei umzubenennen. Natürlich können Sie der Nr. 1 einen anderen Pfad voranstellen, um auch die Datei zu verschieben.
quelle
versuchen Sie diesen Code
quelle
Versuche dies:
quelle
mv
, von denen das letzte (wahrscheinlich) kein Verzeichnis ist. Und es beantwortet die Frage nicht wirklich - der Fragesteller möchte eine bestimmte Anzahl von Dateien verschieben, nicht alle.Ich kam hier vorbei, aber ich musste Dateien in Teilen (jeweils 99) von
/DIR1
nach kopieren/DIR2
. Ich werde das Skript hier einfügen, um anderen zu helfen, vielleicht:quelle
Der folgende Befehl funktioniert, wenn Sie daran interessiert sind
ls
Wie funktioniert das ??
ls -rt source/*
- Befehl listet alle Dateien mit dem relativen Pfad aufhead -n100
- Nimmt die ersten 100 Dateienxargs cp -t destination
- verschiebt diese Dateien in den Zielordnerquelle
Wenn Sie sicher sein möchten / Dateinamen mit Leerzeichen, Zeilenumbrüchen, Anführungszeichen, Backslashes usw. behandeln möchten, müssen Sie durch Null abgeschlossene Trennzeichen verwenden:
EDIT2: HINWEIS: Wenn Sie nicht haben
head -z
( aus irgendeinem Grund ) Sie können das ersetzen obenhead -z -n 1000
mittr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'
(oder andere Art und Weise sehen )-maxdepth 1
Es wird vermieden, in Unterverzeichnissen von nach Dateien zu suchen.$srcdir
Die einzigen aufgelisteten sind die Dateien in$srcdir
.-print0
wird\0
anstelle von newline (\n
) zwischen den einzelnen aufgelisteten Dateien verwendet - dies hilft bei der Behandlung von Dateien mit Zeilenumbrüchen und Leerzeichen mit xargs.head -z
werden\0
terminierte (statt newline (\n
) terminierte) Zeilen als Zeilen gezählt.-n 100
listet nur die ersten gefundenen100
Dateienfind
auf.Wenn Sie sehen möchten, welcher Befehl ausgeführt
xargs
wird, fügen Sie-t
(oder--verbose
) hinzu.xargs -0
"Eingabeelemente werden durch ein Nullzeichen (\0
) anstelle von Leerzeichen abgeschlossen, und die Anführungszeichen und der Backslash sind keine besonderen Zeichen (jedes Zeichen wird wörtlich genommen)"xargs -r
werden nicht ausgeführtmv
wenn keine zu verschiebenden Dateien vorhanden sind (dh wennfind
keine Dateien gefunden wurden).--
Beendet die Verarbeitung von Argumenten als Optionen für das Programm. Weitere Informationen finden Sie hierBeispielausgabe (führt einen
mv
Befehl aus und kann auch Dateien mit Zeilenumbrüchen im Namen verarbeiten):Für
find
:Für
head
:BEARBEITEN: Jemand erwähnte, dass er keine
head -z
hatte. Dies ist die Version, die ich verwendet habe (in Fedora 25):Für
xargs
:Für
cp
:quelle
Ich weiß, dass dieser Thread ziemlich alt ist, aber ich fand die Antworten komplizierter, als ich dachte, dass sie sein sollten. Dies funktionierte in CentOS, aber es scheint einfach genug, dass es wahrscheinlich in anderen Distributionen funktionieren sollte.
quelle
ls
nicht das führendesomedir/
Präfix enthält und nicht für Dateinamen mit Leerzeichen oder Platzhalterzeichen funktioniert oder mit beginnt-
.ls | head -n 100
../someDir100/ aus dem Zielverzeichnis und keiner der Dateinamen erfüllt diese Fälle. Besser glücklich zu sein als gut!