Làm thế nào để sao chép và đổi tên các tập tin được tìm thấy trong hệ thống tìm kiếm chức năng Linux của Linux?


17

Tôi có một thư mục có tên /home/user/temps487 thư mục. Trong mỗi thư mục tôi có một tập tin gọi là thumb.png.

Tôi muốn sao chép tất cả các tệp có tên thumb.png vào một thư mục riêng và đổi tên chúng dựa trên thư mục mà chúng đến.


Đổi tên chúng, làm thế nào? Nếu bạn thay thế dấu phân cách thư mục bằng một cái gì đó - giả sử gạch chân (_), bạn có thể bị va chạm với các tệp chứa phần gạch chân. Điều đó đúng với mọi nhân vật hợp lệ và bên cạnh / và \ 0, bị cấm trong tên tệp, không có bến cảng an toàn - bất kỳ nhân vật nào cũng có thể tạo ra va chạm.
người dùng không xác định

Các thư mục có các thư mục con, hoặc chỉ là một cấu trúc thư mục rộng, đơn giản?
người dùng không xác định

Câu trả lời:


8

Ở đây bạn đi:

for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;

biên tập:

Nhân tiện, sự khôn ngoan kinh điển là việc sử dụng findcho điều này là một ý tưởng tồi - chỉ đơn giản là sử dụng mở rộng vỏ là đáng tin cậy hơn nhiều. Ngoài ra, điều này giả định bash, nhưng tôi cho rằng đó là một giả định an toàn :)

chỉnh sửa 2:

Để rõ ràng, tôi sẽ phá vỡ nó:

# shell-expansion to loop specified files
for file in /home/user/temps/*/thumb.png; do

    # replace 'temps' with 'new_folder' in the path
    # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png'
    new_file=${file/temps/new_folder};

    # drop '/thumb' from the path
    # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png'
    cp "$file" "${new_file/\/thumb/}";
done;

chi tiết về ${var/Pattern/Replacement}cấu trúc có thể được tìm thấy ở đây .

các trích dẫn trong cpdòng rất quan trọng để xử lý các khoảng trắng và dòng mới, v.v. trong tên tệp.


new_file = new_folder? Mục đích của dấu gạch chéo ngược trước dấu gạch chéo là new_file/\/thumbgì?
người dùng không xác định

1
@user: ${VARIABLE/PATTTERN/REPLACEMENT}tạo ra giá trị của VARIABLEnhưng với mẫu thay thế bằng văn bản thay thế. Ở đây mô hình là /thumb( /nhu cầu được thoát ra sao cho nó không giống như thế ${new_file//PATTERN/REPLACEMENT}, điều này làm cho nó thay thế toàn cầu thay vì thay thế lần đầu tiên) và văn bản thay thế trống rỗng.
Gilles 'SO- ngừng trở nên xấu xa'

Tất nhiên, bây giờ tôi thấy nó. :)
người dùng không xác định

1
Bạn đang giả định rằng 487 thư mục nằm ngay dưới /home/user/temps, điều này không rõ ràng trong câu hỏi. Nếu họ không, bạn cần tìm hoặc **.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles - Tôi thực sự, đó là cách tôi đọc câu hỏi. Tuy nhiên, đánh giá cao điểm này
simon

5

Điều này làm việc cho các thư mục con sâu tùy ý:

$ find temps/ -name "thumb.png" | while IFS= read -r NAME; do cp -v "$NAME" "separate/${NAME//\//_}"; done
`temps/thumb.png' -> `separate/temps_thumb.png'
`temps/dir3/thumb.png' -> `separate/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `separate/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `separate/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `separate/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `separate/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `separate/temps_dir2_dir21_thumb.png'

Phần xen kẽ là phần mở rộng tham số ${NAME//\//_} . Nó có nội dung NAMEvà thay thế mọi lần xuất hiện của /với _.

Lưu ý: kết quả phụ thuộc vào thư mục làm việc và tham số đường dẫn cần tìm. Tôi đã thực thi lệnh từ thư mục mẹ của temps. Thay thế cpbằng echođể thử nghiệm.


Thất bại trên các tập tin có chứa một dòng mới trong tên của họ.
người dùng không xác định

Vâng, làm việc rất tốt. một điều nữa, tôi cũng có một vài tệp zip trong một số thư mục con. có thể trích xuất imgae từ đó là tốt. nhớ 'zip not tar'
Mirage

1

Mã trợ giúp ngắn:

#!/bin/bash
#
# echo cp "$1" ../tmp/"${1//\//_}" 
#
mv "$1" ../tmp/"${1//\//_}"

hãy đặt tên cho nó là 'deslash.sh' và làm cho nó có thể thực thi được. Gọi nó với:

find -type f -name thumb.png -exec ./deslash.sh {} ";"    

Nó sẽ thất bại, nếu một vụ va chạm tồn tại

a/b/thumb.png # and 
a_b/thumb.png 

nhưng đó là điều không thể tránh khỏi.


0

Thử đi

mkdir /home/user/thumbs
targDir=/home/user/thumbs

cd /home/user/temps

find . -type d | 
 while IFS="" read -r dir ; do
   if [[ -f "${dir}"/thumb.png ]] ; then
     echo mv -i "${dir}/thumb.png" "${targDir}/${dir}_thumb.png"
   fi
done

Biên tập

Tôi đã thêm trích dẫn trong trường hợp bất kỳ tên dir nào của bạn có ký tự khoảng trắng được nhúng trong chúng.

Ngoài ra tôi đã thay đổi điều này để nó sẽ chỉ in ra các lệnh sẽ được thực thi. Kiểm tra đầu ra của tập lệnh để đảm bảo tất cả các tên tệp / đường dẫn trông phù hợp. Khi bạn chắc chắn không có vấn đề gì với các lệnh sẽ được thực thi, hãy xóa echo.


Tôi có một số tệp png trong một số thư mục con khác, nó sẽ hoạt động
Mirage

đối với phần mềm "A A" của tôi, nó tạo ra: mv -i ./A A/thumb.png ../tmp/.png- tất cả các tệp kết thúc bằng ../tmp/.png (../tmp là thư mục tiêu của tôi).
người dùng không xác định

Thêm dấu ngoặc kép và dấu ngoặc nhọn xung quanh tất cả các biến trong mã ở trên, tức là "$ {dir}"
shellter

@ Mirror51 đã viết: "các tệp trong một số thư mục con khác, sẽ hoạt động được". Có nó nên. Bạn có biết rằng bạn có thể thực hiện riêng từng bước của tập lệnh này (hoặc khi được nối với nhau, từng bộ ống). Bạn có thể thực hiện chỉ find -type dvà xem đầu ra. Điều đó có nhận được tất cả các thư mục bạn mong đợi? Nó nên, nếu không, xin vui lòng thêm một số đầu ra để hiển thị vấn đề. Chúc may mắn.
shellter

Sẽ không làm việc. read dirthực hiện phân tách từ và lấy, từ một thư mục a\nba và b làm hai trường hợp mà không có mặt nạ nào có thể giải quyết.
người dùng không xác định

-1

Để sao chép, bạn cần lệnh cp và đổi tên cho linux cũng giống như di chuyển tệp, vì vậy bạn phải thực hiện bằng lệnh mv . Trong Linux, bạn luôn phải chỉ định toàn bộ đường dẫn, từ nguồn, nếu bạn đang ở trong một thư mục khác, và đến thư mục đích, tất nhiên. Tôi sẽ là một cái gì đó như thế này, để sao chép:

cp /source_path/file /destination_path/

hoặc đổi tên hoặc di chuyển

mv /source_path/old_file /destination_path/new_name_file

Đây chỉ là một phần nhỏ trong câu hỏi của người đăng. Bây giờ giải thích cách lặp qua các thư mục và sao chép hình thu nhỏ :-)

OP muốn sử dụngfind

Vâng, bạn nói đúng ... Tôi không biết chuyện gì đã xảy ra với tôi ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.