Lệnh nào sẽ cung cấp tệp văn bản được phân định bằng tab và cắt mỗi dòng thành 80 ký tự?


8

Tôi đã có các tệp văn bản nhiều dòng dữ liệu được phân định bằng tab (đôi khi). Tôi muốn xuất tệp để tôi có thể lướt qua tệp - vì vậy tôi chỉ muốn nhìn thấy 80 ký tự đầu tiên của mỗi dòng (Tôi đã thiết kế tệp văn bản để đặt nội dung quan trọng lên đầu tiên trên mỗi dòng).

Tôi nghĩ rằng tôi có thể sử dụng con mèo để đọc từng dòng của tệp và gửi từng dòng đến lệnh tiếp theo trong một đường ống:

cat tabfile | cut -c -80

Nhưng điều đó dường như bị phá vỡ. Tôi đã thử khỉ xung quanh và grep dường như hoạt động - nhưng sau đó tôi phát hiện ra rằng, không có gì cả (không phải mỗi dòng trong tệp có hơn 80 ký tự) - xuất hiện các tab được tính là các ký tự đơn bằng cách cắt.

Tôi đã thử:

cat tabfile | tr \t \040 | cut -c -80

Mặc dù điều đó sẽ thu thập dữ liệu của tôi một chút, bằng cách loại bỏ khả năng đọc khoảng trắng. Nhưng điều đó đã không làm việc. Cũng không:

cat tabfile | tr \011 \040 | cut -c -80

Có lẽ tôi đang sử dụng tr sai? Trước đây tôi đã gặp rắc rối với tr, muốn xóa nhiều khoảng trắng (xuất hiện phiên bản tr mà tôi có quyền truy cập trên máy này có tùy chọn -s để nén nhiều ký tự - tôi có thể cần chơi với nó nhiều hơn)

Tôi chắc chắn rằng nếu tôi loay hoay tôi có thể sử dụng perl, awk hoặc sed, hoặc một cái gì đó để làm điều này.

Tuy nhiên, tôi muốn một giải pháp sử dụng các lệnh thông thường (POSIX?), Để nó khả dụng nhất có thể. Nếu tôi kết thúc bằng cách sử dụng tr, cuối cùng tôi có thể thử biến các tab thành ký tự, có thể thực hiện phép tính, cắt tính toán và sau đó biến các ký tự đó trở lại thành các tab cho đầu ra.

Nó không cần phải là một dòng duy nhất / được nhập trực tiếp trên dòng lệnh - một kịch bản là tốt.


Thông tin thêm về các tập tin tab:

Tôi sử dụng tab để ngắt các trường, vì một ngày nào đó tôi có thể muốn nhập dữ liệu vào một số chương trình khác. Vì vậy, tôi có xu hướng chỉ có một tab giữa các phần nội dung. Nhưng tôi cũng sử dụng các tab để sắp xếp mọi thứ với các cột dọc, để hỗ trợ khả năng đọc khi xem tệp văn bản thuần túy. Điều đó có nghĩa là đối với một số phần văn bản tôi đệm phần cuối của nội dung với khoảng trắng cho đến khi tôi đến nơi tab sẽ hoạt động để xếp hàng trường tiếp theo với các phần bên trên và bên dưới nó.

DarkTurerald # 00CED1 Biển, Bầu trời, Rowboats Thiên nhiên
MediumSpringGreen # 00FA9A Hữu ích cho cây Magic  
Vôi # 00FF00 Chỉ để sử dụng cho gà mùa xuân và fru $

Vì vậy, bạn muốn 80 ký tự đếm chiều rộng tab? Bạn có thể thay thế các tab bằng một số lượng không gian thích hợp, sau đó sử dụng cắt.
muru

Annnnnd, làm thế nào để tôi (dễ dàng) mở rộng một nhân vật với nhiều nhân vật? Hoặc, quan trọng hơn, với số lượng ký tự thay đổi (tùy thuộc vào số lượng ký tự khác trong dòng), vì tôi sử dụng tab để sắp xếp thứ tự theo chiều dọc với lượng thông tin khác nhau trước / sau mỗi tab. Như tôi đã nói, nếu tôi muốn học perl / awk / sed Tôi chắc chắn mình có thể, nhưng tôi muốn một cái gì đó đơn giản
user3082

Bạn có thể thử prtừ coreutils: pr -1 -t -l200 -W80 file. Tăng / giảm độ dài trang (số sau -l) theo nhu cầu của bạn.
don_crissti

Don, đề nghị của bạn (tại sao nó không phải là một câu trả lời?) Cho tôi một thông báo lỗi hay. Nhưng con người nói "pr - print files", vì vậy hãy nhìn vào đó.
dùng3082

Don, làm cho câu trả lời này và hãy thảo luận về nó ở đó. Tôi đã có một cái gì đó trông rất giống của bạn - chủ yếu là cùng định dạng, chủ yếu là các cờ giống nhau: -w thay vì -W, v.v ...
user3082

Câu trả lời:


9

Tôi nghĩ rằng bạn đang tìm kiếm expandvà / hoặc unexpand. Có vẻ như bạn đang cố gắng đảm bảo \tchiều rộng ab được tính là 8 ký tự chứ không phải là một ký tự. foldcũng sẽ làm điều đó, nhưng nó sẽ bọc đầu vào của nó vào dòng tiếp theo thay vì cắt ngắn nó. Tôi nghĩ bạn muốn:

expand < input | cut -c -80

expandunexpandcả hai POSIX được chỉ định :

  • Các expandtiện ích có trách nhiệm viết các tập tin hoặc các đầu vào tiêu chuẩn để đầu ra tiêu chuẩn với \tký tự ab thay thế bằng một hoặc nhiều không gian nhân vật cần thiết để pad vào tab dừng chân tiếp theo. Bất kỳ ký tự backspace nào cũng sẽ được sao chép vào đầu ra và làm cho số lượng vị trí cột cho các tính toán dừng tab bị giảm; số lượng vị trí cột không được giảm xuống dưới 0.

Khá đơn giản. Vì vậy, đây là một cái nhìn về những gì nó làm:

unset c i; set --;                                                             
until [ "$((i+=1))" -gt 10 ]; do set -- "$@" "$i" "$i"; done                      
for c in 'tr \\t \ ' expand;  do eval '                                           
    { printf "%*s\t" "$@"; echo; } | 
      tee /dev/fd/2 |'"$c"'| { 
      tee /dev/fd/3 | wc -c >&2; } 3>&1 |
      tee /dev/fd/2 | cut -c -80'
done

Các untilvòng lặp ở đầu được một tập hợp các dữ liệu như ...

1 1 2 2 3 3 ...

Đó printflà điều này với %*scờ đệm arg vì vậy đối với mỗi người trong tập hợp printfsẽ đệm với càng nhiều khoảng trắng trong số của đối số. Đối với mỗi người, nó gắn thêm một \tký tự ab.

Tất cả các tees được sử dụng để hiển thị các hiệu ứng của từng bộ lọc khi nó được áp dụng.

Và những ảnh hưởng là:

1        2        3        4        5        6        7        8                9               10
1  2   3    4     5      6       7        8         9         10 
1  2   3    4     5      6       7        8         9         10 
66
1        2        3        4        5        6        7        8                9               10
1        2        3        4        5        6        7        8                9               10 
1        2        3        4        5        6        7        8                
105

Những hàng đó được xếp thành hai bộ như ...

  1. đầu ra của printf ...; echo
  2. đầu ra của tr ...hoặcexpand
  3. đầu ra của cut
  4. đầu ra của wc

Bốn hàng trên cùng là kết quả của trbộ lọc - trong đó mỗi \tab được chuyển đổi thành một khoảng trắng .

Và bốn kết quả dưới cùng của expandchuỗi.


1
Trên thực tế, đừng quan tâm (quá nhiều) nếu \ t được tính là 8 (5?) Hoặc một, chỉ là nó không được tính là một và hiển thị là 8.
user3082

+ @ anon3202 - làm cho ý nghĩa hoàn hảo. Tôi hiểu ý của bạn - (và nhân tiện, chiều dài dừng của tab là tùy chọn cli) - Tôi chỉ không nói điều đó tốt nhất có thể. Hy vọng bạn có được ý chính - như tôi lấy nó bạn có thể có.
mikeerv

Tôi đã không hoàn toàn làm theo lời giải thích, nhưng lúng túng với các chương trình mở rộng cho thấy việc mở rộng chắc chắn là điều tôi đang tìm kiếm.
dùng3082

3

Vì các tab dành cho căn chỉnh nhiều hơn là phân định, nên một cách có thể là sử dụng columnvà sau đó cut:

column -s '\t' -t <some-file | cut -c -80

Có vẻ như columnkhông phải là POSIX. Nó là một phần của các tiện ích BSD trên Ubuntu, vì vậy tôi cho rằng nó khá đa nền tảng.


Sử dụng columncách này OP thậm chí sẽ không cần thêm khoảng trắng thủ công để căn chỉnh.
Beni Cherniavsky-Paskin

1

Đề nghị của Don trong ý kiến ​​là một khởi đầu tốt.

Đây là những gì tôi cần để làm cho nó (hầu hết) hoạt động:

pr +1 -1 -t -m -l1000 -w 80 tabfile

Điều -mcần thiết là làm cho -wcờ có hiệu lực trên một cột duy nhất. Trang người đàn ông có thể sử dụng một số viết lại để chỉ ra rằng.

Khi thử một cách giải quyết, tôi thấy rằng prxuất ra các \tký tự, do đó, việc cung cấp kết quả của nó sẽ cutdẫn đến cùng một vấn đề.

-1 (cờ cột) nói cụ thể trong trang man:

Tùy chọn này không nên được sử dụng với -m.

Tuy nhiên, không có tùy chọn này prcắt ngắn các dòng willy-nilly, với độ dài ngắn hơn nhiều so với độ dài quy định.

prcũng chèn một khoảng trắng trước (hoặc sau?) mỗi từ trong một trường (tức là mỗi nơi tôi có một khoảng trắng, có hai khoảng trắng sau khi xử lý). Nếu có quá nhiều từ, các khoảng trắng được chèn sẽ bỏ qua các -whạn chế (tạo ra bao quanh). Nhưng, tò mò, mặt khác - không phân định tab (nghĩa là khoảng trắng được sắp xếp) 'các cột' được xếp hàng.



0

Một tiện ích cần thực sự nhận biết chiều rộng hiển thị là fold: thật không may, nó dường như không có tùy chọn để loại bỏ thay vì bọc. Mặc dù nó có thể không hiệu quả khủng khiếp, tuy nhiên bạn có thể làm một cái gì đó như

while read -r line; do fold -w80 <<< "$line" | head -n1; done < file
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.