2016-02-17 16 views
7

Đôi khi tôi có một lớp lót mà tôi lặp lại nhiều lần cho một tác vụ cụ thể, nhưng có khả năng sẽ không bao giờ sử dụng lại dưới dạng chính xác. Nó bao gồm tên tệp mà tôi đang dán từ danh sách thư mục. Một nơi nào đó ở giữa và tạo ra một kịch bản bash Tôi nghĩ có lẽ tôi chỉ có thể tạo ra một chức năng one-liner tại dòng lệnh như:Xác định chức năng trong dòng lệnh unix/linux (ví dụ: BASH)

numresults(){ ls "$1"/RealignerTargetCreator | wc -l } 

Tôi đã thử một vài điều như sử dụng eval, sử dụng numresults=function..., nhưng thiên đường' t vấp phải cú pháp đúng và chưa tìm thấy bất kỳ thứ gì trên web cho đến nay. (Tất cả mọi thứ sắp tới chỉ là hướng dẫn về các chức năng bash).

+0

cho tôi biết số lượng tệp trong thư mục '$ 1/RealignerTargetCreator'. – abalter

Trả lời

8

Trích dẫn my answer cho một câu hỏi tương tự như trên Hỏi Ubuntu:

Chức năng trong bash được về cơ bản được đặt tên lệnh ghép (hoặc mã khối). Từ man bash:

Compound Commands 
    A compound command is one of the following: 
    ... 
    { list; } 
      list is simply executed in the current shell environment. list 
      must be terminated with a newline or semicolon. This is known 
      as a group command. 

... 
Shell Function Definitions 
    A shell function is an object that is called like a simple command and 
    executes a compound command with a new set of positional parameters. 
    ... [C]ommand is usually a list of commands between { and }, but 
    may be any command listed under Compound Commands above. 

Không có lý do gì, đó chỉ là cú pháp.

Hãy thử bằng dấu chấm phẩy sau wc -l:

numresults(){ ls "$1"/RealignerTargetCreator | wc -l; } 
+0

Vâng, điều đó thật đơn giản! (Tôi có nghĩa là dấu chấm phẩy). Một lần nữa, nó luôn luôn tốt để có được một sự hiểu biết sâu hơn về cách thức hoạt động của vỏ. – abalter

+1

Dấu chấm phẩy là cần thiết vì '}' không phải là một ký tự điều khiển và không chấm dứt một lệnh. Chú ý 'echo}' chỉ đơn giản là kết quả đầu ra chuỗi chữ. – chepner

+0

@chepner Đó chỉ là đẩy câu hỏi xuống một cấp. Những người tạo ra ngữ pháp có thể làm cho '}' đặc biệt cho các hàm. zsh, ví dụ, không có vấn đề với 'foo() {echo foo}'. – muru

3

Không sử dụng ls | wc -l vì nó có thể cung cấp cho bạn kết quả sai nếu tên tập tin có dòng mới trong đó. Bạn có thể sử dụng hàm này thay thế:

numresults() { find "$1" -mindepth 1 -printf '.' | wc -c; } 
+0

Cảm ơn. Nó luôn luôn tốt để làm sâu sắc thêm kỹ năng bash của một người! Chỉ cần tò mò, làm thế nào có thể một tên tập tin có một dòng mới trong nó? – abalter

+0

Bạn có thể sử dụng tệp 'touch $' \ nvới \ nline'' để tạo tên tệp với dòng mới – anubhava

+1

Đó là điều xấu xa. – abalter

-2

Cách dễ nhất có thể là lặp lại những gì bạn muốn quay lại.

function myfunc() 
{ 
    local myresult='some value' 
    echo "$myresult" 
} 

result=$(myfunc) # or result=`myfunc` 
echo $result 

Dù sao here bạn có thể tìm thấy một tốt how-to cho các mục đích nâng cao hơn

2

Bạn cũng có thể đếm tập tin mà không find. Sử dụng các mảng,

numresults() { local files=("$1"/*); echo "${#files[@]}"; } 

hoặc sử dụng tham số vị trí

numresults() { set -- "$1"/*; echo "$#"; } 

Để phù hợp với các tập tin ẩn là tốt,

numresults() { local files=("$1"/* "$1"/.*); echo $(("${#files[@]}" - 2)); } 
numresults() { set -- "$1"/* "$1"/.*; echo $(("$#" - 2)); } 

(Trừ 2 từ kết quả đền bù cho ....)

+1

Hàm đầu tiên của các tệp ẩn có thể sử dụng 'dotglob', vì nó vẫn sử dụng mảng. – muru

+0

Hm, vì lý do nào đó, tôi nhớ 'dotglob' khớp' .' và '..', nhưng không. – chepner

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