it-swarm-vi.com

Làm cách nào để di chuyển 100 tệp từ thư mục chứa hàng nghìn?

Tôi có một thư mục với hàng ngàn tập tin. Làm cách nào tôi có thể di chuyển 100 tệp (bất kỳ tệp nào sẽ làm) sang vị trí khác.

43
gaijin
for file in $(ls -p | grep -v / | tail -100)
do
mv $file /other/location
done

Giả sử tên tệp không chứa khoảng trắng, dòng mới (giả sử giá trị mặc định là $IFS), ký tự đại diện (?, *, [) hoặc bắt đầu bằng -.

36
ennuikiller

Nó dễ nhất trong zsh:

mv -- *([1,100]) /other/location/

Thao tác này sẽ di chuyển 100 tệp không bị ẩn đầu tiên (thuộc bất kỳ loại nào, thay đổi ([1,100]) đến (.[1,100]) for chỉ các tệp thông thường hoặc (^/[1,100]) cho bất kỳ loại nào nhưng thư mục ) theo thứ tự từ điển tên. Bạn có thể chọn một thứ tự sắp xếp khác với ovòng loại toàn cầ , ví dụ: để di chuyển 100 tệp cũ nhất:

mv -- *(Om[1,100]) /other/location/

Với các shell khác, bạn có thể thực hiện nó trong một vòng lặp với lối ra sớm.

i=0
for x in *; do
  if [ "$i" = 100 ]; then break; fi
  mv -- "$x" /other/location/
  i=$((i+1))
done

Một cách di động khác sẽ là xây dựng danh sách các tệp và xóa tất cả trừ 100 cuối cùng .

Nếu bạn không sử dụng zsh:

set -- *
[ "$#" -le 100 ] || shift "$(($# - 100))"
mv -- "[email protected]" /target/dir

Sẽ di chuyển cái cuối cùng (theo thứ tự bảng chữ cái) 100 cái.

8
Stéphane Chazelas

Sau đây làm việc cho tôi. Xin lỗi nếu nó đã được đăng trước đó, nhưng tôi đã không nhìn thấy nó trong một lần quét nhanh.

ls path/to/dir/containing/files/* | head -100 | xargs -I{} cp {} /Path/to/new/dir
5
Joe

Các oneliner sau trong Shell sẽ giúp.

[.__.] foreach i (`find Source_Directory -type f --max-height 1 | tail -100`); làm; {mv $ i Target_Directory}; làm xong
3
diham
3
den2042

mmv là một tiện ích nổi bật cũng sẽ cho phép bạn thực hiện đổi tên hàng loạt các tệp. (Tôi phải Sudo apt-get install mmv trên máy tính của tôi để cài đặt nó.) Ví dụ sử dụng đơn giản: giả sử bạn có một thư mục các tệp có phần mở rộng .JPG mà bạn muốn thay đổi thành chữ thường .jpg. Lệnh sau thực hiện thủ thuật:

mmv \*.JPG \#1.jpg

Dấu gạch chéo ngược được sử dụng để hiển thị ký tự đại diện sắp xuất hiện. */JPG phù hợp với mọi thứ có phần mở rộng JPG. Trong phần "đến" của lệnh, số 1 sử dụng văn bản phù hợp từ ký tự đại diện đầu tiên để đổi tên tệp. Tất nhiên, bạn có thể đặt một đường dẫn khác trước số 1 để di chuyển tệp.

1
Pete
#!/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

thử mã này

1
juicebyah

lệnh sau hoạt động, nếu bạn muốn sử dụng ls

$ ls -rt source/* | head -n100 | xargs cp -t destination

Cái này hoạt động ra sao ??

  • ls -rt source/* - lệnh liệt kê tất cả các tệp có đường dẫn tương đối
  • head -n100 - mất 100 tệp đầu tiên
  • xargs cp -t destination - di chuyển các tệp này vào thư mục đích
1
Rohith Yeravothula

Thử cái này:

find /source/directory -type f -maxdepth 1 -print | tail -100 | xargs -J % mv % /other/location/
0
Saumil

Nếu bạn muốn an toàn/xử lý tên tệp có dấu cách, dòng mới, dấu ngoặc kép, dấu gạch chéo ngược, v.v., chúng phải sử dụng dấu phân cách kết thúc null:

find "$srcdir" -maxdepth 1 -type f -print0 | head -z -n 100 | xargs -0 -r -- mv -t "$destdir" --

EDIT2: LƯU Ý: nếu bạn không có head -z ( vì bất kỳ lý do gì ) bạn có thể thay thế head -z -n 1000 ở trên bằng tr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0' (hoặc xem các cách khác )

-maxdepth 1 Sẽ tránh tìm kiếm các tệp trong thư mục con của $srcdir, Do đó, những tệp duy nhất được liệt kê là các tệp trong $srcdir.
[.__.] -print0 Sẽ sử dụng \0 Thay vì dòng mới (\n) Giữa mỗi tệp được liệt kê - điều này giúp xử lý các tệp chứa dòng mới và dấu cách bằng xargs.
[.__.] head -z Sẽ tính \0 Đã chấm dứt (thay vì dòng mới (\n) Chấm dứt dưới dạng dòng. -n 100 Sẽ chỉ liệt kê các tệp 100 Đầu tiên mà find được tìm thấy.
[.__.] Nếu bạn muốn xem lệnh nào xargs sẽ thực thi, hãy thêm -t (Hoặc --verbose).
[.__.] xargs -0 "Các mục đầu vào được chấm dứt bằng ký tự null (\0) Thay vì bằng khoảng trắng, và dấu ngoặc kép và dấu gạch chéo ngược không đặc biệt (mọi ký tự được lấy theo nghĩa đen)"
[.__.] xargs -r Sẽ không chạy mv nếu không có tệp nào được di chuyển (ví dụ: if find không tìm thấy bất kỳ tệp nào).
[.__.] -- Chấm dứt xử lý các đối số dưới dạng tùy chọn cho chương trình, chi tiết hơn tại đây

Đầu ra mẫu (chạy một lệnh mv và cũng có thể xử lý các tệp có dòng mới trong tên của chúng):

$ 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'

Dành cho 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.

Dành cho 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

EDIT: Ai đó đã đề cập rằng họ không có head -z, Đây là phiên bản mà tôi đang sử dụng (trong 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

Dành cho 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.

Dành cho cp:

-t, --target-directory=DIRECTORY
       copy all SOURCE arguments into DIRECTORY
-v, --verbose
       explain what is being done
0
user306023

Tôi đã đến đây, nhưng tôi cần sao chép các tập tin trong các phần (99 mỗi phần) từ /DIR1 đến /DIR2. Tôi sẽ dán tập lệnh ở đây để giúp người khác có thể:

#!/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
0
Enissay

Một biến thể khác, lấy cảm hứng từ https://unix.stackexchange.com/a/105042/66736 :

cp `ls -d ./* | head -n 100` tmpi

Nó có thể không phải là cách nhanh nhất hoặc thanh lịch nhất, nhưng đó là cách bạn có thể ghi nhớ.

0
lucidbrot