2013-09-04 52 views
31

Tôi có một lệnh BASH đơn giản mà trông giống nhưChuyển hướng đầu ra của bash vòng lặp for

for i in `seq 2`; do echo $i; done; > out.dat 

Khi điều này chạy đầu ra của seq 2 là đầu ra cho thiết bị đầu cuối và không có gì là đầu ra cho các tập tin dữ liệu (out.dat)

tôi hy vọng tiêu chuẩn ra được chuyển hướng tới out.dat như nó chỉ đơn giản là chạy lệnh seq 2 > out.dat

Trả lời

60

Xóa dấu chấm phẩy của bạn.

for i in `seq 2`; do echo "$i"; done > out.dat 

ĐỀ XUẤT

Cũng theo đề nghị của Fredrik Pihl, cố gắng không sử dụng các chương trình ngoài khi họ không cần thiết, hoặc ít nhất là khi thực tế không:

for i in {1..2}; do echo "$i"; done > out.dat 
for ((i = 1; i <= 2; ++i)); do echo "$i"; done > out.dat 
for i in 1 2; do echo "$i"; done > out.dat 

Ngoài ra, hãy cẩn thận các đầu ra trong words có thể gây ra việc mở rộng tên đường dẫn.

for A in $(echo '*'); do echo "$A"; done 

Sẽ hiển thị tệp của bạn thay vì chỉ là một chữ *.

$() cũng được đề xuất như là một cú pháp rõ ràng hơn cho thay thế lệnh trong Bash và POSIX shell so với backticks (`), và nó hỗ trợ làm tổ.

Các giải pháp sạch hơn cũng cho đọc đầu ra để biến là

while read VAR; do 
    ... 
done < <(do something) 

read ... < <(do something) ## Could be done on a loop or with readarray. 

for A in "${ARRAY[@]}"; do 
    : 
done 

Sử dụng printf cũng có thể là một sự thay thế dễ dàng hơn đối với các chức năng dự định với:

printf '%s\n' {1..2} > out.dat 
+1

Tại sao 'seq' thay vì' cho i trong {1..2}; làm ... '? –

+0

@FredrikPihl Có nó tốt hơn. Hoặc '((i = 1; i <= 2; ++ i))' hoặc đơn giản là 'trong 1 2' để tương thích. Câu trả lời của tôi chỉ là về vấn đề với chuyển hướng, mặc dù tôi đã cố sửa lỗi: '" $ i "'. – konsolebox

+0

Tôi chỉ nghĩ rằng bạn có thể cập nhật câu trả lời của mình bằng cách thay thế * cách tốt hơn để giải quyết vấn đề mà không cần sử dụng các tệp nhị phân bên ngoài :-) –

5

Hãy thử:

(for i in `seq 2`; do echo $i; done;) > out.dat 
+0

Đã hiệu quả. Có một tài nguyên mà tôi có thể đọc về những gì dấu ngoặc đơn làm/tại sao nó được yêu cầu. Hay bạn có thể giải thích? –

+3

Không cần đặt nó trên một vỏ bọc con. Dấu chấm phẩy chỉ cần được loại bỏ để làm cho phần chuyển hướng của khối. – konsolebox

+2

Đúng, chỉ cần xóa dấu chấm phẩy sẽ làm trong trường hợp này. Subshell,(), có thể được sử dụng để thu thập đầu ra từ số lượng lệnh lớn hơn, cho biết nhiều vòng lặp for. – svante

6

Một khả năng khác, vì mục đích hoàn chỉnh: Bạn có thể di chuyển đầu ra bỏ vòng lặp, sử dụng >> để nối thêm vào tệp, nếu nó tồn tại.

for i in `seq 2`; do echo $i >> out.dat; done; 

Cái nào tốt hơn chắc chắn phụ thuộc vào trường hợp sử dụng. Viết các tập tin trong một đi chắc chắn là tốt hơn so với phụ thêm vào nó một ngàn lần. Ngoài ra, nếu vòng lặp chứa nhiều câu lệnh echo, tất cả đều sẽ chuyển đến tệp, làm done > out.dat có thể dễ đọc hơn và dễ bảo trì hơn. Ưu điểm của giải pháp này, tất nhiên, là nó mang lại sự linh hoạt hơn.

+3

Thực hiện một chuyển hướng bên ngoài vòng lặp chắc chắn là tốt hơn cho hiệu suất. – tripleee

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