chia dòng dài trên một dấu phân cách


21

Tôi có thể sử dụng lệnh nào để phân chia đầu vào như thế này:

foo:bar:baz:quux

vào đây?

foo
bar
baz
quux

Tôi đang cố gắng tìm ra cutlệnh nhưng dường như nó chỉ hoạt động với số lượng đầu vào cố định, như "1000 ký tự đầu tiên" hoặc "7 trường đầu tiên". Tôi cần phải làm việc với đầu vào dài tùy ý.


5
Ý bạn là như thế tr : '\n' < inputnào?
jw013

Bạn đang sử dụng vỏ gì? bash?
glenn jackman

Câu trả lời:


34

Có một vài tùy chọn:

  • tr : \\n
  • sed 's/:/\n/g'
  • awk '{ gsub(":", "\n") } 1'

Bạn cũng có thể làm điều này trong sạch bash:

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done

3
Lưu ý rằng việc sử dụng \ntrong chuỗi thay thế như thế sẽ hoạt động trong GNU sed, nhưng sẽ thất bại trong hầu hết các triển khai sed khác.
wjv

@chrisdown Có cách nào để hai người đầu tiên làm việc trong AIX không?
cokedude

4
$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux

4

Nếu grep của bạn hỗ trợ, -obạn có thể làm như thế này:

grep -o '[^:]\+'

Hoặc với awk, đặt dấu tách bản ghi thành ::

awk -v RS=: 1

Hoặc với GNU cut:

cut -d: --output-delimiter=$'\n' -f1-

Chỉnh sửa

Như Chris đã lưu ý dưới đây, điều này sẽ để lại một dòng mới, điều này có thể tránh được nếu awk của bạn hỗ trợ chỉ định RSlà biểu thức chính quy (được thử nghiệm với GNU awk):

awk -v RS='[:\n]' 1

awkVí dụ của bạn sẽ để lại một dòng mới (có thể không mong muốn).
Chris Xuống

@ChrisDown: bạn nói đúng, điều này có thể tránh được nếu RS có thể là biểu thức chính quy.
Thor

-1

Trong một số chuỗi tôi đã có vấn đề với các giải pháp ở trên. Nhưng điều này làm việc cho tôi:

echo $string | sed 's/\\n/ /g' | tr " " \\n

Như đã viết, điều này không biến đổi đầu vào ví dụ OP.
kbulgrien
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.