Lặp qua các tập tin không bao gồm các thư mục


11

Tôi cần tập lệnh của mình để làm một cái gì đó cho mọi tệp trong thư mục hiện tại không bao gồm bất kỳ thư mục con nào.

Ví dụ: trong đường dẫn hiện tại, có 5 tệp, nhưng 1 trong số đó là một thư mục (thư mục con). Kịch bản của tôi sẽ kích hoạt một lệnh được đưa ra làm đối số khi chạy tập lệnh đã nói. Tức là "bash script wc -w" sẽ cung cấp số đếm từ của mỗi tệp trong thư mục hiện tại, nhưng không phải bất kỳ thư mục nào, để đầu ra không bao giờ có bất kỳ dòng "/ sub / dir: Is thư mục" nào.

Kịch bản hiện tại của tôi:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

Tôi chỉ cần loại trừ các thư mục cho vòng lặp, nhưng tôi không biết làm thế nào.

Câu trả lời:


11
#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Lưu ý rằng nó cũng loại trừ các tệp thuộc loại symlink và trong đó symlink phân giải thành một tệp có thư mục loại (có thể là những gì bạn muốn).

Thay thế (từ ý kiến), chỉ kiểm tra các tệp:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done

@roaima ý hay!
laktak

2
Tốt hơn để sử dụng if [ -f "$file" ]; then .... Không phải một thư mục sẽ trả về không chỉ các tệp thông thường mà cả các socket và symlink.
JRFerguson

@JRFerguson dựa trên câu hỏi của OP Tôi sẽ nói rằng bao gồm cả ổ cắm và đường ống sẽ là một ý tưởng thực sự tồi tệ. Đối với các liên kết tượng trưng, ​​chúng được bao gồm trong ! -dđó.
roaima

Tôi đã sử dụng [-f $ file] trong tập lệnh cuối cùng của mình. Lưu ý thiếu dấu ngoặc kép trong điều kiện if. Hầu như mọi nơi tôi nhìn đều có dấu ngoặc kép quanh tệp $, nhưng tôi phải xóa chúng để kịch bản của tôi hoạt động.
Tõni Piip

3

Đây là một cách thay thế cho việc sử dụng vòng lặp for nếu những gì bạn cần làm là đơn giản (và không liên quan đến việc đặt các biến trong shell chính & c).

Bạn có thể sử dụng findvới -execvà sử dụng -maxdepth 1để tránh đệ quy vào thư mục con.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

[ -n "$1" ]để tránh thực thi tất cả các tệp trong thư mục khi tập lệnh không vượt qua bất kỳ đối số nào.


2

Trong zsh, bạn có thể sử dụng vòng loại toàn cầu để hạn chế kết hợp ký tự đại diện theo loại tệp. Ví dụ, thêm (.)sau khi mẫu giới hạn nó vào các tệp thông thường.

wc -w *(.)

Để đối phó với tên tệp bắt đầu bằng -hoặc ., sử dụng wc -c -- *(.N)hoặc wc -c ./*(.N). Nếu bạn muốn bao gồm các liên kết tượng trưng cho các tệp thông thường, hãy làm điều đó *(-.).

Các shell phổ biến khác không có tính năng như vậy, vì vậy bạn cần sử dụng một số cơ chế khác nhau để lọc theo tệp, chẳng hạn như kiểm tra các loại tệp trong một vòng lặp hoặc find.


0

Bash cho vòng lặp không bao gồm các thư mục con ('/') và các liên kết (@):

for f in `ls|egrep -v '/|@'`; do echo $f; done
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.