2009-12-29 2 views
34

tôi nhận ra làm thế nào để làm điều đó trong python, chỉ vớiLàm cách nào để tách một dòng thành các từ được phân tách bằng một hoặc nhiều dấu cách trong bash?

line = db_file.readline() 
ll=string.split(line) 

nhưng làm thế nào tôi có thể làm điều tương tự trong bash? là nó thực sự có thể làm điều đó một cách rất đơn giản?

+0

Tôi nghĩ bạn có nghĩa là 'll = str.split (dòng)' trong Python. – Arthur

Trả lời

4

Tùy chọn -a của read sẽ cho phép bạn chia dòng được đọc bởi các ký tự có trong $IFS.

+0

#/bin/bash filename = $ 1 khi đọc ĐƯỜNG DÂY làm \t echo $ Line! | đọc -a xong <$ filename nó có hoạt động không? – asdf

+0

Không, -a sẽ là một đối số cho lần đọc đầu tiên. "giúp đọc" tại một dòng lệnh bash sẽ, uh ... giúp đỡ. –

+2

@asdf: Nó sẽ trông giống như sau: 'filename = $ 1; trong khi đọc -a LINE; làm echo "$ LINE"; thực hiện <"$ filename" ' –

9
$ line="these are words" 
$ ll=($line) 
$ declare -p ll # dump the array 
declare -a ll='([0]="these" [1]="are" [2]="words")' 
$ for w in ${ll[@]}; do echo $w; done 
these 
are 
words 
+1

+1 để dạy tôi tùy chọn -p – grok12

110
s='foo bar baz' 
a=($s) 
echo ${a[0]} 
echo ${a[1]} 
... 
+1

i này những gì tôi đang tìm kiếm, cảm ơn – asdf

+14

Điều này phải được đánh dấu là câu trả lời đúng – jaywink

+0

Biến thể nội tuyến: BAR =" $ (a = ($ value); echo $ {a [1]})" –

28

Nó phụ thuộc vào những gì bạn có ý nghĩa bởi chia. Nếu bạn muốn lặp qua các từ trong một dòng, đó là trong một biến, bạn chỉ có thể lặp lại. Ví dụ: giả sử biến số linethis is a line. Sau đó, bạn có thể làm điều này:

for word in $line; do echo $word; done 

này sẽ in:

this 
is 
a 
line 

for .. in $var chia $var sử dụng các giá trị trong $IFS, giá trị mặc định có nghĩa là "khoảng trống phân chia và dòng mới".

Nếu bạn muốn đọc các dòng từ người dùng hoặc một tập tin, bạn có thể làm một cái gì đó như:

cat $filename | while read line 
do 
    echo "Processing new line" >/dev/tty 
    for word in $line 
    do 
     echo $word 
    done 
done 

Đối với bất cứ điều gì khác, bạn cần phải rõ ràng hơn và xác định câu hỏi của bạn một cách chi tiết hơn.

Lưu ý: Đã chỉnh sửa để xóa bashism, nhưng tôi vẫn giữ cat $filename | ... vì tôi thích nó hơn chuyển hướng.

+5

Sử dụng vô dụng 'cat' - chuyển hướng tệp như sau:' done <"$ filename" '. Ngoài ra, hãy sử dụng 'for value in" $ {var [@]} "' trong ngữ cảnh này thay vì một biến chỉ mục. Trong trường hợp này mảng có thể tiếp giáp, Bash hỗ trợ mảng thưa thớt và '$ {# var [@]}' có thể không phải là mục cuối cùng (mặc dù '$ {var [@]: -1}' sẽ là và 'chỉ mục = ($ {! a [@]}); count = $ {# index [@]} 'sẽ đưa ra danh sách các chỉ số và số đếm chính xác) –

+1

@Dennis: Tất cả các điểm tốt. Tôi quen với 'mèo a | blah' thay vì 'blah

+1

Cách tiếp cận này sẽ thất bại nếu bạn có dấu sao (*) trong dòng $. Bash sẽ thay thế nếu với danh sách tập tin trong thư mục hiện hành. – crenate

2

Nếu bạn đã có dòng lại văn bản trong một $ line biến, sau đó bạn sẽ có thể nói

for L in $LINE; do 
    echo $L; 
done 
9

làm điều này

while read -r line 
do 
    set -- $line 
    echo "$1 $2" 
done <"file" 

$ 1, $ 2 vv sẽ là 1 và 2 "trường" được chia nhỏ. sử dụng $ @ để nhận tất cả các giá trị .. sử dụng $ # để nhận được độ dài của "trường".

+1

Lưu ý rằng nếu '$ line' của bạn chứa e.g. '*', điều này sẽ được mở rộng bằng bash khi thực hiện 'set - $ line', có thể có những hiệu ứng đáng ngạc nhiên. – clacke

+0

1) "-" làm gì? 2) Hiệu ứng đáng ngạc nhiên nào có thể mở rộng * có? – Xofo

27

Nếu bạn muốn một từ cụ thể từ dòng, awk có thể hữu ích, ví dụ:

 
$ echo $LINE | awk '{print $2}' 

In từ được tách biệt khoảng trắng thứ hai trong $ LINE. Bạn cũng có thể chia nhỏ các ký tự khác, ví dụ:

 
$ echo "5:6:7" | awk -F: '{print $2}' 
6 
+1

Đây là lý do của tôi để bắt đầu sử dụng awk ngay bây giờ. Không giống như tạo mảng và thêm dòng. -F: chỉ phát nổ từ: trong một dòng. Yêu nó, thx. – erm3nda

+0

hơn nữa: 'echo" 5 :: 6: 7 "| awk -F :: '{print $ 2}' ' ' 6: 7' (khác với cắt, chỉ lấy một ký tự làm dấu phân tách) – ribamar

5

More đơn giản,

echo $line | sed 's/\s/\n/g' 

\s --> whitespace character (space, tab, NL, FF, VT, CR). In many systems also valid [:space:]

\n --> new line

15
echo $line | tr " " "\n" 

cho đầu ra tương tự như hầu hết các câu trả lời ở trên; mà không sử dụng vòng lặp.


Trong trường hợp của bạn, bạn cũng có đề cập đến ll=<...output...>,
như vậy, (cho rằng tôi không biết nhiều trăn và giả sử bạn cần phải gán đầu ra cho một biến),

ll=`echo $line | tr " " "\n"` 

nên đủ (nhớ đến echo "$ll" thay vì echo $ll)