Respuestas:
for file in $(ls -p | grep -v / | tail -100)
do
mv $file /other/location
done
Esto supone nombres de los archivos no contienen espacios en blanco, de nueva línea (suponiendo que el valor por defecto de $IFS
), los caracteres comodín ( ?
, *
, [
) o empezar con -
.
ls
. Y siempre entre comillas dobles de parámetros y sustituciones de comandos.
find
faltaba mi comando. Un argumento estaba en el lugar equivocado, y he agregado terminaciones de nombre de archivo nulo. Es un poco largo de una sola línea, pero eso es todo lo que puedo hacer en un comentario. Aquí está el fragmento fijo:find . -maxdepth 1 -type f \( ! -iname ".*" \) -print0 | while read -rd $'\0' file ; do mv -- "$file" /other/location/ ; done
read -d
opción no es portátil para todos los shells, pero si está usando de bash
todos modos, -d ''
debería obtener el mismo efecto que -d $'\0'
.
;
donde está cada nueva línea ahora.
Es más fácil en zsh:
mv -- *([1,100]) /other/location/
Esto mueve los primeros 100 archivos no ocultos (de cualquier tipo, cambie ([1,100])
a solo (.[1,100])
para archivos normales , o (^/[1,100])
para cualquier tipo que no sea directorio ) en orden lexicográfico de nombre. Puede seleccionar un orden de clasificación diferente con el o
calificador global , por ejemplo, para mover los 100 archivos más antiguos:
mv -- *(Om[1,100]) /other/location/
Con otros proyectiles, puede hacerlo en un bucle con una salida anticipada.
i=0
for x in *; do
if [ "$i" = 100 ]; then break; fi
mv -- "$x" /other/location/
i=$((i+1))
done
Otra forma portátil sería construir la lista de archivos y eliminar todos menos los últimos 100 .
$(( i++ ))
o $[ i++ ]
?
++
y --
. Puedes escribir en : $((i+=1))
lugar de i=$((i+1))
; No estoy convencido de que sea más legible.
ls -p | grep -v /
también tiene la pregunta reciente que se duplica aquí.
Si no estás usando zsh:
set -- *
[ "$#" -le 100 ] || shift "$(($# - 100))"
mv -- "$@" /target/dir
Movería los últimos (en orden alfabético) 100 unidades.
El siguiente oneliner en shell ayudaría.
foreach i (`find Source_Directory -type f --max-depth 1 | tail -100`); hacer; {mv $ i Target_Directory}; hecho
zsh
incluso si a primera vista parece bastante ajeno a la zsh
sintaxis. Gilles ha mostrado una forma mucho más simple de hacerlo zsh
. Incluso entonces, eso es aún más confiable que la respuesta actualmente aceptada.
shuf -n 100 -e * | xargs -i mv {} path-to-new-folder
mmv es una utilidad excepcional que también te permitirá cambiar el nombre de los archivos en masa. (Tuve sudo apt-get install mmv
que instalarlo en mi computadora). Ejemplo de uso simple: suponga que tiene un directorio de archivos con extensión .JPG que desea cambiar a minúscula .jpg. El siguiente comando hace el truco:
mmv \*.JPG \#1.jpg
La barra invertida se usa para mostrar que se está acercando un comodín. El * / JPG coincide con cualquier cosa con una extensión JPG. En la parte "a" del comando, el # 1 usa el texto correspondiente del primer comodín para cambiar el nombre del archivo. Por supuesto, puede poner una ruta diferente antes del # 1 para mover también el archivo.
el siguiente comando funciona, si está interesado en usar ls
$ ls -rt source/* | head -n100 | xargs cp -t destination
Como funciona esto ??
ls -rt source/*
- el comando enumera todos los archivos con la ruta relativahead -n100
- toma los primeros 100 archivosxargs cp -t destination
- mueve estos archivos a la carpeta de destinoPrueba esto:
find /source/directory -type f -maxdepth 1 -print | tail -100 | xargs -J % mv % /other/location/
mv
, el último de los cuales (probablemente) no es un directorio. Y en realidad no responde a la pregunta: el autor de la pregunta quiere mover un número determinado de archivos, no todos.
Vine aquí, pero necesitaba copiar archivos en partes (99 cada uno) de /DIR1
a /DIR2
. Pegaré el script aquí para ayudar a otherz tal vez:
#!/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
Si desea estar seguro / manejar nombres de archivos con espacios, líneas nuevas, comillas, barras invertidas, etc., debe usar separadores con terminación nula:
find "$srcdir" -maxdepth 1 -type f -print0 | head -z -n 100 | xargs -0 -r -- mv -t "$destdir" --
EDIT2: NOTA: si no tiene head -z
( por alguna razón ) puede reemplazar lo anterior head -z -n 1000
con tr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'
(o ver otras formas )
-maxdepth 1
evitará buscar archivos en subdirectorios de $srcdir
, por lo que los únicos enumerados son los archivos dentro $srcdir
.
-print0
usará en \0
lugar de nueva línea ( \n
) entre cada archivo de la lista; esto ayuda a manejar archivos que contienen nuevas líneas y espacios con xargs.
head -z
contará las líneas \0
terminadas (en lugar de newline ( \n
) terminadas) como líneas. -n 100
enumerará solo los primeros 100
archivos que find
encontró.
Si desea ver qué comando xargs
se ejecutará, agregue -t
(o --verbose
).
xargs -0
"Los elementos de entrada terminan con un carácter nulo ( \0
) en lugar de un espacio en blanco, y las comillas y la barra diagonal inversa no son especiales (cada carácter se toma literalmente)"
xargs -r
no se ejecutarámv
si no hay archivos para mover (es decir, si find
no encontró ningún archivo).
--
termina el procesamiento de argumentos como opciones para el programa, más detalles aquí
Salida de muestra (ejecuta un mv
comando y también puede manejar archivos con nuevas líneas en su nombre):
$ 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'
Para 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.
Para 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
EDITAR: Alguien mencionó que no tenían head -z
, esta es la versión que estaba usando (en 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
Para 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.
Para cp
:
-t, --target-directory=DIRECTORY
copy all SOURCE arguments into DIRECTORY
-v, --verbose
explain what is being done
Otra variación, inspirada en https://unix.stackexchange.com/a/105042/66736 :
cp `ls -d ./* | head -n 100` tmpi
Puede que no sea la forma más rápida o más elegante, pero es una forma que puede guardar en la memoria.
Sé que este hilo es bastante antiguo, pero encontré las respuestas más complicadas de lo que pensé que deberían ser. Esto funcionó en CentOS, pero parece bastante simple que probablemente debería funcionar en otras distribuciones.
cp `ls someDir | head -n 100` someDir100/
ls
no incluirá el somedir/
prefijo inicial, y no funcionará para el nombre de archivo con caracteres en blanco o comodín ni comenzará con -
.
ls | head -n 100
../someDir100/ Desde dentro del directorio de destino y ninguno de los nombres de archivo satisfizo esos casos. ¡Mejor tener suerte que bien!
about.com
y a otro sitio web para obtener la lista de opciones disponibles que posiblemente puedo usar ... pero no encontré nada comotail