Làm cách nào tôi có thể sử dụng cột để phân định trên các tab và không phải khoảng trắng?


59

Tôi muốn sử dụng columnlệnh Unix để định dạng một số văn bản. Tôi có các trường được phân cách bằng các tab, nhưng trong mỗi trường cũng có khoảng trắng. columnphân định trên khoảng trắng (tab và dấu cách). Làm cách nào để tạo cột chỉ sử dụng các tab làm dấu phân cách?

Tôi đã cố gắng chỉ định tab là dấu phân cách bằng cách sử dụng:

cat myfile | column -t -s"\t"

Câu trả lời:


82
column -t -s '\t'

sẽ tách các cột trên \và các tký tự.

column -s \tcũng giống như column -s t, dấu gạch chéo ngược được hiểu là toán tử trích dẫn bởi shell.

Ở đây bạn muốn chuyển một ký tự TAB thực sự vào cột. Với ksh93, zsh, bash, mksh, busybox sh hoặc FreeBSD sh:

column -ts $'\t'

Hoặc nhập một ký tự tab thực bằng cách nhập Ctrl-V Tabvào dấu nhắc shell (trong dấu ngoặc kép hoặc trước dấu gạch chéo ngược vì ký tự tab là dấu tách mã trong cú pháp shell giống như dấu cách) hoặc sử dụng "$(printf '\t')"(những dấu ngoặc kép đó cần để vô hiệu hóa dấu tách + global toán tử là ký tự tab cũng xảy ra ở giá trị mặc định của $IFS).


3
Tôi phải làm column -t -s $'\t'như bash dường như nghĩ rằng '\t'có nghĩa là cả hai \ t, nhưng $'\t'có nghĩa là một tab chữ. Bash bốc mùi
ThorSummoner

Nếu bạn cần sự khen ngợi POSIX (chúa giúp tôi), xin vui lòng xem câu trả lời của tôi, chủ yếu dựa trên câu trả lời tuyệt vời này!
Nick Bull

Giải pháp này hiệu quả với tôi - $'\t'tab làm cho dấu phân cách. Nhưng tôi khá chắc chắn rằng tôi sẽ awk -F "\t"sử dụng một tab làm dấu phân cách cho awk. Tại sao điều đó làm việc và không ở đây cho cột?
Mike

3

Tôi đã sử dụng như sau (chỉ hoạt động nếu văn bản của bạn không chứa |):

cat myfile | tr '\t' '|' | column -t -s '|'

Điều này chỉ thay thế các tab bằng đường ống, sau đó sử dụng cột với đường ống làm dấu phân cách.

(Tôi đã làm điều này bởi vì tôi đã không thấy bất cứ điều gì trong câu trả lời của Stéphane có tác dụng ngoài hộp cá.


3

Đối với POSIX, $'...'được gọi là thoát ANSI-C, không được xác định.

Thay vào đó, bạn có thể sử dụng $(printf '\t'):

column -t -s "$(printf '\t')"

$(printf '\011')có thể được sử dụng, vì 011(biểu diễn bát phân của số thập phân 9) là mã ANSI cho ký tự tab ngang:

column -t -s "$(printf '\011')"

Tuy nhiên, xem bình luận dưới đây từ Stéphane Chazelas về lý do tại sao điều này có thể không nhất quán trên các phiên bản vỏ.


2
Lưu ý rằng POSIX không chỉ định mã hóa của TAB là gì. Vẫn còn các hệ thống POSIX có mã hóa ngôn ngữ C là EBCDIC dựa trên TAB là 5, không phải 9 như trong ASCII. Bất cứ nơi nào có thể, tốt hơn là tham khảo các ký tự theo tên để tránh loại vấn đề này giống "$(printf '\t')"như trong câu trả lời của tôi. Lưu ý rằng $'...'được lên kế hoạch để đưa vào phiên bản chính tiếp theo của thông số kỹ thuật POSIX.
Stéphane Chazelas

@ StéphaneChazelas là $(printf '\t')POSIX? Cảm ơn bạn!
Nick Bull


@ StéphaneChazelas Cảm ơn bạn rất nhiều, tôi đã cập nhật câu trả lời của mình để bao gồm mẹo rất hữu ích của bạn :)
Nick Bull

2

Đây -tlà để chọn số lượng cột bạn muốn. Để trống này không thay đổi bất cứ điều gì. Ngoài ra, bạn muốn có khoảng trắng sau khi -sthử, hãy thử điều này:

cat myfile | column -s \t


Cảm ơn. Điều này gần với những gì tôi đang tìm kiếm. Tuy nhiên, bây giờ tất cả các dòng được hợp nhất vào một dòng. Làm thế nào tôi có thể giữ mỗi dòng trên dòng riêng của mình?
rùa

Theo mặc định, columnđiền vào các hàng trước cột. Bạn có thể quan tâmpr
lurker
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.