Đặt cược tốt nhất hiện tại của tôi là:
for i in $(find . -name *.jpg); do echo $i; done
Vấn đề: không xử lý khoảng trắng trong tên tệp.
Lưu ý: Tôi cũng thích một cách đồ họa để thực hiện việc này, chẳng hạn như lệnh "cây".
Đặt cược tốt nhất hiện tại của tôi là:
for i in $(find . -name *.jpg); do echo $i; done
Vấn đề: không xử lý khoảng trắng trong tên tệp.
Lưu ý: Tôi cũng thích một cách đồ họa để thực hiện việc này, chẳng hạn như lệnh "cây".
Câu trả lời:
Cách kinh điển là làm
find . -name '*.jpg' -exec echo {} \;
(thay thế \;
bằng +
để truyền nhiều hơn một tệp echo
cùng một lúc)
hoặc (GNU cụ thể, mặc dù hiện tại một số BSD cũng có nó):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
để mở rộng các chuỗi thoát như \b
(ít nhất là các tuân thủ Unix echo
).
find
trang web hiển thị find . -type f -exec file '{}' \;
trong EXAMPLES
phần. Có thể một số vỏ sẽ điều trị niềng răng đặc biệt.
'{}'
, \{\}
, {}
, "{}"
, '{'}
được mở rộng bằng vỏ (bất kể Bourne giống như vỏ) để một đối số để thấy rằng là hai nhân vật "{" và "}". Thay thế "find" bằng "echo find" hoặc printf '<%s>\n' find
nếu bạn muốn kiểm tra lại.
Câu trả lời tốt hơn đã được đưa ra.
Nhưng lưu ý rằng không gian không phải là vấn đề duy nhất trong mã bạn đã đưa ra. tab, dòng mới và ký tự đại diện cũng là một vấn đề.
Với
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
Sau đó, chỉ có các nhân vật dòng mới là một vấn đề.
Những gì bạn đã đề cập là một trong những vấn đề cơ bản mà mọi người gặp phải, khi họ cố gắng đọc tên tệp. Đôi khi, những người có kiến thức hạn chế và có quan niệm sai lầm về cấu trúc tệp và thư mục có xu hướng quên rằng " Trong UNIX Mọi thứ đều là tệp ". Vì vậy, họ không hiểu rằng họ cũng cần xử lý khoảng trắng, vì tên tệp có thể bao gồm 2 hoặc nhiều từ có khoảng trắng.
Giải pháp: Vì vậy, một trong những cách được biết đến nhiều hơn để làm điều này là đọc sạch .
Chúng tôi ở đây sẽ đọc tất cả các tệp có mặt và giữ chúng trong một biến, lần tới khi thực hiện xử lý mong muốn, chúng tôi sẽ phải giữ biến đó trong dấu ngoặc kép để giữ tên tệp có dấu cách. Đây là một trong những cách cơ bản để làm điều đó, tuy nhiên, các câu trả lời khác được cung cấp bởi những người khác ở đây cũng hoạt động tốt.
KỊCH BẢN :
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
Ở đây tôi đang đọc các tệp bằng cách đưa đường dẫn cho chúng và bất cứ điều gì tôi đang đọc tôi đều giữ chúng bên trong một biến I, mà tôi sẽ trích dẫn ở điểm sau trong khi xử lý nó để giữ khoảng trống để xử lý chính xác.
Hy vọng điều này sẽ giúp bạn một cách nào đó.
Đơn giản chỉ với find
và bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
Bằng cách này, chúng tôi sử dụng $1
trong bash, như trong một kịch bản cơ bản, mở ra những viễn cảnh tốt đẹp để thực hiện bất kỳ nhiệm vụ nâng cao (hoặc không) nào.
Một cách hiệu quả hơn (để tránh phải bắt đầu bash mới cho mỗi tệp):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
Trong phiên bản gần đây của bash, bạn có thể sử dụng globstar
tùy chọn:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Đối với các hành động đơn giản, bạn thậm chí có thể bỏ qua hoàn toàn vòng lặp:
echo **/*.jpg
set -G
), nhưng nó không nên được sử dụng trong bash vì phiên bản bash bị phá vỡ cơ bản (giống như GNU grep -r
) khi nó đi vào liên kết tượng trưng đến các thư mục (tương đương find -L
hoặc zsh ***/*.jpg
). Cũng lưu ý rằng trái với tìm kiếm, nó sẽ xuất hiện các dotfiles và không rơi xuống dotdirs (theo mặc định).
$i
? Tôi làm điều đó và nó hoạt động tốt. Có điều gì sai với cách tiếp cận đó?