Debido a que Unix y Linux no tienen un gran sitio web sobre sus herramientas, simplemente voy al sitio web como about.comy a otro sitio web para obtener la lista de opciones disponibles que posiblemente puedo usar ... pero no encontré nada comotail
gaijin
Respuestas:
36
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 -.
Tenga en cuenta que este enfoque solo funciona si no hay caracteres especiales (espacios en blanco, caracteres no imprimibles, ``) en los nombres de archivo. Como regla general, no analice la salida dels . Y siempre entre comillas dobles de parámetros y sustituciones de comandos.
Gilles 'SO- deja de ser malvado'
1
¿Qué parte representa 100 archivos?
tshepang
3
Actualización de mi comentario anterior: después de leer el enlace de referencia de Gilles, no analice la salida de ls , descubrí que findfaltaba 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
Peter
@perer Solo como una nota de que la read -dopción no es portátil para todos los shells, pero si está usando de bashtodos modos, -d ''debería obtener el mismo efecto que -d $'\0'.
jw013
FWIW, si desea que esto se ejecute como una línea, agregue un lugar ;donde está cada nueva línea ahora.
patrick
37
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 ocalificador 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
@phk, eso funcionaría zshincluso si a primera vista parece bastante ajeno a la zshsintaxis. 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.
mmv es una utilidad excepcional que también te permitirá cambiar el nombre de los archivos en masa. (Tuve sudo apt-get install mmvque 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.
Sería más beneficioso si proporcionara cómo utilizaría realmente la herramienta que sugiere para lograr el objetivo.
Dason
1
se agregó un ejemplo de uso
Pete el
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
Esto es incorrecto, le está pasando tres argumentos 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.
Mat
Comando actualizado.
Saumil
0
Vine aquí, pero necesitaba copiar archivos en partes (99 cada uno) de /DIR1a /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:
EDIT2: NOTA: si no tiene head -z( por alguna razón ) puede reemplazar lo anterior head -z -n 1000con tr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'(o ver otras formas )
-maxdepth 1evitará buscar archivos en subdirectorios de $srcdir, por lo que los únicos enumerados son los archivos dentro $srcdir. -print0usará en \0lugar 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 -zcontará las líneas \0terminadas (en lugar de newline ( \n) terminadas) como líneas. -n 100enumerará solo los primeros 100archivos que findencontró.
Si desea ver qué comando xargsse 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 -rno se ejecutarámvsi no hay archivos para mover (es decir, si findno encontró ningún archivo). --termina el procesamiento de argumentos como opciones para el programa, más detalles aquí
Salida de muestra (ejecuta un mvcomando 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
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.
Eso no funciona porque la salida de lsno incluirá el somedir/prefijo inicial, y no funcionará para el nombre de archivo con caracteres en blanco o comodín ni comenzará con -.
Stéphane Chazelas
Lo suficientemente justo. Realmente hice cp 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
Respuestas:
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-
.fuente
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 debash
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:
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 elo
calificador global , por ejemplo, para mover los 100 archivos más antiguos:Con otros proyectiles, puede hacerlo en un bucle con una salida anticipada.
Otra forma portátil sería construir la lista de archivos y eliminar todos menos los últimos 100 .
fuente
$(( i++ ))
o$[ i++ ]
?++
y--
. Puedes escribir en: $((i+=1))
lugar dei=$((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:
Movería los últimos (en orden alfabético) 100 unidades.
fuente
Lo siguiente funcionó para mí. Lo siento si se publicó anteriormente, pero no lo vi en un escaneo rápido.
fuente
El siguiente oneliner en shell ayudaría.
fuente
zsh
incluso si a primera vista parece bastante ajeno a lazsh
sintaxis. Gilles ha mostrado una forma mucho más simple de hacerlozsh
. Incluso entonces, eso es aún más confiable que la respuesta actualmente aceptada.Desde https://stackoverflow.com/questions/14033129/how-to-move-a-given-number-of-random-files-on-unix-linux-os
fuente
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: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.
fuente
prueba este código
fuente
el siguiente comando funciona, si está interesado en usar
ls
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 destinofuente
Prueba esto:
fuente
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:fuente
Si desea estar seguro / manejar nombres de archivos con espacios, líneas nuevas, comillas, barras invertidas, etc., debe usar separadores con terminación nula:
EDIT2: NOTA: si no tiene
head -z
( por alguna razón ) puede reemplazar lo anteriorhead -z -n 1000
contr '\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 primeros100
archivos quefind
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, sifind
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):Para
find
:Para
head
:EDITAR: Alguien mencionó que no tenían
head -z
, esta es la versión que estaba usando (en Fedora 25):Para
xargs
:Para
cp
:fuente
Otra variación, inspirada en https://unix.stackexchange.com/a/105042/66736 :
Puede que no sea la forma más rápida o más elegante, pero es una forma que puede guardar en la memoria.
fuente
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.
fuente
ls
no incluirá elsomedir/
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!