2012-02-24 39 views
10

Tôi có một tập lệnh xuất ra khoảng 10 dòng mỗi khi nó chạy. Nội dung của các dòng này thay đổi.Có thể đường ống vào câu lệnh if không?

Tôi thực sự muốn có thể grep ở đầu ra và thực hiện những việc khác nhau tùy thuộc vào đầu ra.

Trong giả này là những gì tôi muốn làm

cat /etc/password | \\ 
if [ grep "root" $STDOUT ]; then 
    echo "root is found" 

elif [ grep "nobody" $STDOUT ]; then 
    echo "nobody is found" 

fi 

Ở đây có tôi đã sử dụng cat /etc/password làm ví dụ, nhưng nó phải được thay thế bằng các kịch bản của tôi đề cập ở trên.

Vấn đề là, làm cách nào để giữ đầu ra từ cat /etc/password trong các điều kiện if/elif?

+1

lẽ awk hoặc perl là phù hợp hơn cho nhiệm vụ của bạn .. – bew

+2

không sử dụng 'cat' nếu ý định không hiển thị hoặc ghép nối. Ở đây bạn chỉ có thể cung cấp cho các tập tin trong dòng lệnh grep, bởi vì nó được chấp nhận, nếu không bạn chỉ có thể chuyển hướng tập tin ('<'). – Benoit

+2

Bạn không cần tiếp tục dòng sau '|', '&&' và '||' –

Trả lời

5

Vì @Benoit đề xuất, chỉ cần sử dụng trực tiếp grep.

Khi @larsmans ghi chú, bạn có thể tránh đọc hai lần tệp bằng cách đọc nó thành biến một lần.

Với sự sẵn có của bash tôi muốn làm điều đó như thế này:

password=$(< /etc/passwd) 

if grep -q root <<< "$password" ; then 
    echo root found 
elif grep -q nobody <<< "$password" ; then 
    echo nobody found 
fi 

Một đọc của tập tin, một hoặc hai lời gọi của grep, không có quy trình khác hoặc subshells đưa ra.

+0

Giải pháp rất thú vị. Tại sao bạn có 'IFS =' trên dòng đầu tiên? –

+2

Trong bash, bạn chỉ có thể nói 'password = $ (

+0

Một điểm tốt glenn, tôi đã quên điều này. – Sorpigal

3

Bạn chỉ cần làm:

if grep -q "root" /etc/passwd ; then 
    ... 
fi 

mà sẽ đóng ... lệnh nếu mã thoát grep là 0.

nhớ rằng \[ is a external command, có lẽ nằm ở /usr/bin/[ (thường đó là một liên kết cứng đến test và khi được gọi là [ nó yêu cầu đối số ] phù hợp). Ngoài ra, hãy xem trang pitfalls tại đây, nhiều giao dịch trong số đó có liên quan đến lệnh đó.

+1

+1, nhưng bạn có thể muốn thêm '-q' vào' grep' để chặn đầu ra. – Sorpigal

1

Đường ống vào một tuyên bố nếu có thể với subshells, nhưng giải pháp đó sẽ phá vỡ kể từ khi bạn đang chạy hai grep lệnh trên đường ống, đầu tiên trong số đó sẽ xả nó.

Giải pháp tốt nhất trong trường hợp của bạn có lẽ là để đọc /etc/passwd vào một biến, sau đó grep nó:

passwd=$(cat /etc/passwd) 
if (echo $passwd | grep -q root); then 
    echo "root found" 
fi 
if (echo $passwd | grep -q nobody); then 
    echo "nobody found" 
fi 
+0

Nó rẻ hơn để nói 'IFS = read-r -d' 'mật khẩu Sorpigal

+0

Ok, nhưng tôi không thấy cách đảm bảo -1. –

+2

Không. Tôi không biết ai đã làm điều đó, nhưng tôi đã phản đối bỏ phiếu trong sự phẫn nộ. – Sorpigal

3

tôi muốn đề nghị sử dụng awk:

cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }' 

Bạn có thể đạt được như vậy trong bash sử dụng cụm từ như:

cat /etc/passwd | 
while read; do 
    if echo "$REPLY" | fgrep root; then 
    something 
    fi 
    if echo "$REPLY" | fgrep nobody; then 
    something_else 
    fi 
done 

Tuy nhiên, ba thuần túy sh giải pháp là ít hiệu quả cho đầu vào lớn bởi vì nó chạy trường hợp riêng biệt của grep cho mỗi dòng.

+0

Không sử dụng 'cat' như thế, bạn có thể chuyển' passwd' trực tiếp đến 'awk',' while', v.v. – Sorpigal

+1

Đúng, nhưng thường dễ đọc hơn theo cách này vì nguồn dữ liệu là ở phía trước, và để phân tích một vài chục dòng hiệu suất thực sự không phải là một vấn đề. Ở quy mô này, nó chỉ là vấn đề sở thích cá nhân và không phải là lý do để bỏ phiếu. –

0

Trong trường hợp chung, bạn có thể sử dụng tệp tạm thời.

t=$(mktemp -t passwd.XXXXXXXX) 
trap 'rm $t' 0 
trap 'exit 127' 1 2 3 5 15 
cat >$t 
for u in root nobody; do 
    fgrep $u $t 
done 

trap s để xóa tệp tạm thời sau đó.

Là một sang một bên, bạn có thể ống đến một if, nhưng grep đầu tiên trong điều kiện của bạn sẽ đã tiêu thụ tất cả các đầu vào tiêu chuẩn của nó. Đó là hữu ích hơn trong những tình huống như thế này:

if $option_count ; then 
    wc -l 
else 
    tac 
fi <file 
1

Chỉ cần sử dụng & &:

grep -q root /etc/password && echo "root is found" 

grep -q nobody /etc/password && echo "nobody is found" 
0

Làm thế nào về những điều sau đây:

#!/bin/bash 

if [ -z $1 ]; then 
    echo Usage: $0 [UID to search for] 
    exit 1; 
fi 

SEARCHID="$1" 

function notFound() { 
    echo NOT FOUND 
} 

function found() { 
    echo Found it 
} 

function main() { 

    grep -i $SEARCHID /etc/passwd 
    # Move $? to a variable 
    SEARCHRESULT=$? 

    if [ "$SEARCHRESULT" != "0" ]; then 
     notFound; 
    else 
     found; 
    fi 
} 

# call main function 
main 
Các vấn đề liên quan