2010-10-25 24 views
26

nhanh Bối cảnh:Bash Đối-Vòng trên Thư mục

$ ls src 
file1 file2 dir1 dir2 dir3 

Script:

#!/bin/bash 

for i in src/* ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 

Output:

src/dir1 
src/dir2 
src/dir3 

Tuy nhiên, tôi muốn nó đọc:

dir1 
dir2 
dir3 

Bây giờ tôi nhận ra tôi có thể sed/awk đầu ra để loại bỏ "src /" tuy nhiên tôi tò mò muốn biết nếu có một cách tốt hơn để đi về việc này. Có lẽ sử dụng một tìm + while-loop thay thế.

Trả lời

16

Làm điều này thay thế cho dòng echo:

echo $(basename "$i") 
+0

Tôi thấy bạn đã cập nhật bài đăng của mình để đọc * basename * thay vì * dirname * ding, ding, ding CORRECT !!! : D Cảm ơn, tôi sẽ chấp nhận câu trả lời của bạn – BassKozz

+0

Đã học được điều này nugget chỉ 2 ngày trước từ một cuốn sách O'Rielly. Có thể đã tiết kiệm cho tôi giờ của tomfoolery sed nếu tôi biết nó năm trước đây. – Synesso

3

Sử dụng basename như:

if [ -d "$i" ]; then 
    basename "$i" 
fi 
10

Không cần forking một quá trình bên ngoài:

echo "${i##*/}" 

nó sử dụng “loại bỏ tiền tố trùng khớp dài nhất ”parameter expansion. */ là mẫu, do đó, nó sẽ xóa mọi thứ từ đầu chuỗi đến và bao gồm dấu gạch chéo cuối cùng. Nếu không có dấu gạch chéo trong giá trị của $i, thì nó giống như "$i".

Mở rộng thông số cụ thể này là specified in POSIX và là một phần của di sản của vỏ Bourne gốc. Nó được hỗ trợ trong tất cả các vỏ Bourne-like (sh, tro, dash, ksh, bash, zsh, vv). Nhiều trong số các shell có nhiều tính năng (ví dụ: ksh, bashzsh) có các mở rộng khác có thể xử lý nhiều hơn mà không liên quan đến các quy trình bên ngoài.

8

Nếu bạn thực hiện cd khi bắt đầu tập lệnh, nó sẽ được hoàn nguyên khi tập lệnh thoát.

#!/bin/bash 

cd src 
for i in * ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 
+2

nên ... nhưng nếu bạn sử dụng lệnh '.' hoặc' source' để gọi tập lệnh, nó sẽ không. Thay vì sử dụng 'pushd' và' popd'. – Benoit

Các vấn đề liên quan