2009-10-01 21 views
23

Tôi có một chương trình C xuất ra hai cột, hoàn toàn không đúng giá trị. Lý do cho sự lệch hướng là độ dài của các từ trong cột đầu tiên là rất khác nhau.Tôi làm cách nào để có thể xóa các cột không được căn lề trong văn bản?

Tôi có tệp đầu ra được mở trong vi. Làm cách nào để nhanh chóng căn chỉnh hai cột này? Tôi tốt với việc sử dụng awk, perl, sed, và không chỉ vi (7.2) toolset. Ngoài ra, chúng ta có thể có một giải pháp chung cho các tệp có nhiều hơn hai cột không?

Đây là mẫu tập tin

column1    column2 
-------    ------- 
sdfsdfsddfsdfsdfsdfsd   343r5 
dfgdfgdf    234 
gdfgdfgdfgdfgf   645 

Trả lời

26

Có lẽ bạn đang sử dụng printf để sản xuất các cột ở nơi đầu tiên. Bạn có thể sử dụng các công cụ sửa đổi bổ sung trong chuỗi định dạng của mình để đảm bảo mọi thứ được căn chỉnh.

  • Để in cột có chiều rộng cụ thể (phải được biện minh), thêm chiều rộng trước cờ định dạng, ví dụ: "% 10s" sẽ in một cột có chiều rộng 10. Nếu chuỗi của bạn dài hơn 10 ký tự , cột sẽ dài hơn bạn muốn, vì vậy hãy chọn giá trị tối đa. Nếu chuỗi ngắn hơn, nó sẽ được đệm bằng dấu cách.
  • Để căn trái một cột, hãy đặt dấu - ở trước, ví dụ: "% -10s". Tôi thích để trái-biện minh cho dây và phải biện minh cho con số, cá nhân.
  • Nếu bạn đang in địa chỉ, bạn có thể thay đổi các ký tự điền từ dấu cách sang số không với số 0 đứng đầu: "% 010x".

Để cung cấp một nhiều trong ví dụ sâu:

printf("%-30s %8s %8s\n", "Name", "Address", "Size"); 
for (i = 0; i < length; ++i) { 
    printf("%-30s %08x %8d\n", names[i], addresses[i], sizes[i]); 

này sẽ in ba cột như thế này:

Name       Address  Size 
foo      
bar       9abcdef0  1024 
something-with-a-longer-name 0000abcd  2048 
9

Dưới đây là một giải pháp awk: c_prog | awk '{ printf("%- 40s %- 40s\n", $1, $2); }'

2

Tôi đã viết một nhỏ chương trình giải quyết vấn đề này bằng Perl. Nó cũng hoạt động cho nhiều cột.

#!/usr/bin/perl 
use strict; 
use warnings; 
my $sep = 2; 

sub max { 
    my ($a,$b) = @_; 
    return $a > $b ? $a : $b; 
} 

my @rows; 
my $cols; 
my $max = 0; 

while (<>) { 
    next if m/^\s*$/; 
    my (@cols) = split m'\s+'; 

    for (@cols) { 
     $max = max($max, length); 
    } 

    $cols = @cols; 
    push @rows, \@cols; 
} 

for (@rows) { 
    my $str = join '', (('%-' . ($max+$sep) . 's') x $cols); 
    $str .= "\n"; 
    printf $str, @$_; 
} 
4

Nếu bạn muốn làm việc xử lý trong Vim (như trái ngược với sửa chữa máy phát điện), cài đặt tuyệt vờialign plugin và chạy như sau:

ggVG 
\tsp 

Các vi phạm lệnh đầu tiên xuống gg (chuyển đến đầu tệp), V (nhập chế độ dòng trực quan), G (chuyển đến cuối tệp). Như một sự kết hợp, nó trực quan chọn toàn bộ tập tin. \tsp là bản đồ Căn chỉnh căn chỉnh trên khoảng trắng.

Nếu bạn thích làm mọi thứ tại dòng : lệnh, bạn có thể sử dụng một tách thay thế (ví dụ ###) và sử dụng các dòng lệnh Align:

:%s/\s\+/###/g 
:%Align ### 
:%s/### //g 

Đó là lâu hơn, nhưng bạn có thể tìm thấy nó hơn hợp lý/đáng nhớ.

33

Đối với một sửa chữa nhanh chóng-và-bẩn, ống thông qua cột:

your_program | column -t 

Nếu bạn cần bao gồm các không gian trong các dữ liệu cột, sau đó phân định các lĩnh vực với một số nhân vật như "|" và:

your_program | column -t -s "|" 

Bạn có thể sử dụng bất kỳ ký tự nào cho dấu phân cách và chỉ định ký tự đó bằng công tắc -s. Có thể kiểm soát các ký tự nhưng có một chút phức tạp hơn để làm việc.

Nhưng khi Jay đề cập bạn nên tắt chương trình để định dạng đầu ra đúng cách.

+0

Bạn có thể sử dụng tính năng Bash để dễ dàng chỉ định ký tự điều khiển, ví dụ Tab: 'column -t -s $ '\ t'' –

+0

Cảnh báo: cột không giống các dòng" quá dài "và trong khi' cột người đàn ông' đề cập đến giới hạn ở 2048 byte, trong thực tế, một vài trăm byte đủ để choke nó (trên Debian 8.3 ít nhất). –

2

Tôi chỉ cần thêm mất tích trong một lựa chọn câu trả lời:

Emacs với Mx class-regexp, Mx class-chuỗi vv đọc thêm tại http://www.emacswiki.org/emacs/AlignCommands

POSIX vỏ (có thể xây dựng-in) lệnh printf:

while read f1 f2 f3 tail; do printf "%10s %5s | %s" $f1 $f3 $tail; done <file.txt 
Các vấn đề liên quan