Perintah apa yang akan memberi makan file teks dibatasi-tab dan memotong setiap baris hingga 80 karakter?


8

Saya punya beberapa file teks baris (kadang-kadang) data dibatasi-tab. Saya ingin menampilkan file sehingga saya dapat meliriknya - jadi saya hanya ingin melihat 80 karakter pertama dari setiap baris (saya merancang file teks untuk menempatkan hal-hal penting terlebih dahulu di setiap baris).

Saya pikir saya bisa menggunakan cat untuk membaca setiap baris file, dan mengirim setiap baris ke perintah berikutnya dalam sebuah pipa:

cat tabfile | cut -c -80

Tapi itu sepertinya rusak. Saya mencoba bermain-main, dan grep tampaknya bekerja - tetapi kemudian saya menemukan bahwa, tidak, tidak (tidak setiap baris dalam file memiliki 80+ karakter) - tampaknya tab dihitung sebagai karakter tunggal dengan dipotong.

Saya mencoba:

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

Meskipun itu akan sedikit mengacaukan data saya, dengan menghilangkan keterbacaan ruang putih. Tapi itu tidak berhasil. Tidak juga:

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

Mungkin saya menggunakan tr salah? Saya pernah mengalami masalah dengan tr sebelumnya, ingin menghapus beberapa spasi (muncul versi tr yang saya akses di mesin ini memiliki opsi -s untuk memeras beberapa karakter - saya mungkin perlu lebih banyak bermain dengan itu)

Saya yakin jika saya bermain-main saya bisa menggunakan perl, awk atau sed, atau sesuatu untuk melakukan ini.

Namun, saya ingin solusi yang menggunakan perintah biasa (POSIX?), Sehingga se portable mungkin. Jika saya akhirnya menggunakan tr, saya mungkin akhirnya akan mencoba mengubah tab menjadi karakter, mungkin melakukan perhitungan, memotong perhitungan, dan kemudian mengubah karakter tersebut kembali menjadi tab untuk output.

Tidak perlu satu baris / dimasukkan langsung pada baris perintah - skrip baik-baik saja.


Info lebih lanjut tentang file-tab:

Saya menggunakan tab untuk memecah bidang, karena suatu hari nanti saya mungkin ingin mengimpor data ke beberapa program lain. Jadi saya cenderung hanya memiliki satu tab di antara potongan konten. Tapi saya juga menggunakan tab untuk menyelaraskan hal-hal dengan kolom vertikal, untuk membantu keterbacaan saat melihat file teks biasa. Yang berarti untuk beberapa bagian teks, saya mengisi bagian akhir konten dengan spasi hingga saya sampai di tempat tab akan bekerja dalam menyejajarkan bidang berikutnya dengan yang di atas dan di bawahnya.

DarkTurquoise # 00CED1 Lautan, Langit, Alam Perahu Dayung
MediumSpringGreen # 00FA9A Berguna untuk Pohon Ajaib  
Lime # 00FF00 Hanya untuk digunakan pada ayam spring dan fru $

Jadi Anda ingin 80 karakter menghitung lebar tab? Anda bisa mengganti tab dengan jumlah spasi yang sesuai, lalu gunakan potong.
muru

Selain itu, bagaimana cara (dengan mudah) memperluas satu karakter dengan banyak karakter? Atau, yang lebih penting, dengan jumlah karakter yang bervariasi (tergantung pada berapa banyak karakter lain dalam barisan), karena saya menggunakan tab untuk menyejajarkan barang secara vertikal dengan jumlah info yang berbeda sebelum / setelah setiap tab. Seperti yang saya katakan, jika saya ingin belajar perl / awk / sed saya yakin saya bisa, tetapi saya menginginkan sesuatu yang sederhana
user3082

Anda bisa mencoba prdari coreutils: pr -1 -t -l200 -W80 file. Menambah / mengurangi panjang halaman (nomor setelah -l) sesuai kebutuhan Anda.
don_crissti

Don, saran Anda (mengapa bukan jawaban?) Memberi saya pesan kesalahan yang bagus. Tetapi manusia mengatakan "file pr-print", jadi melihat ke dalamnya.
user3082

Don, buat ini jawaban dan mari kita diskusikan di sana. Saya punya sesuatu yang sangat mirip milik Anda - kebanyakan format yang sama, sebagian besar bendera yang sama: -w bukan -W, dll ...
user3082

Jawaban:


9

Saya pikir Anda sedang mencari expanddan / atau unexpand. Tampaknya Anda mencoba untuk memastikan \tlebar ab dihitung sebagai 8 karakter daripada yang tunggal. foldakan melakukannya juga, tetapi akan membungkus inputnya ke baris berikutnya daripada memotongnya. Saya pikir Anda ingin:

expand < input | cut -c -80

expanddan unexpandkeduanya ditentukan POSIX :

  • The expandutilitas akan menulis file atau standar input ke output standar dengan \tkarakter ab diganti dengan satu atau lebih ruang karakter yang dibutuhkan untuk pad ke tab perhentian berikutnya. Setiap karakter backspace harus disalin ke output dan menyebabkan jumlah posisi kolom untuk penghentian tab-tab dikurangi; hitungan posisi kolom tidak akan dikurangi di bawah nol.

Cukup mudah. Jadi, inilah yang dilihatnya:

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

The untilLoop di atas mendapat satu set data seperti ...

1 1 2 2 3 3 ...

Ini printfadalah ini dengan %*sflag padding arg sehingga untuk masing-masing orang di set printfakan pad dengan ruang sebanyak dalam jumlah argumen. Untuk masing-masing menambahkan \tkarakter ab.

Semua tees digunakan untuk menunjukkan efek dari setiap filter saat diterapkan.

Dan efeknya adalah ini:

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

Baris-baris itu berbaris dalam dua set seperti ...

  1. output dari printf ...; echo
  2. output dari tr ...atauexpand
  3. output dari cut
  4. output dari wc

Empat baris teratas adalah hasil dari trfilter - di mana setiap \tab dikonversi ke ruang tunggal .

Dan empat terbawah adalah hasil dari expandrantai.


1
Sebenarnya, tidak peduli (terlalu banyak) jika \ t dihitung sebagai 8 (5?) Atau satu, hanya saja itu tidak dihitung sebagai satu dan ditampilkan sebagai 8.
user3082

+ @ anon3202 - sangat masuk akal. Saya mengerti apa yang Anda maksud - (dan tab stop length adalah opsi cli, by the way) - Saya hanya tidak mengatakannya sebaik yang saya bisa. Semoga Anda mendapatkan intinya - seperti yang saya ambil mungkin Anda miliki.
mikeserv

Saya tidak cukup mengikuti penjelasannya, tetapi berkeliling dengan memperluas menunjukkan bahwa memperluas pasti apa yang saya cari.
user3082

3

Karena tab lebih untuk penyejajaran daripada pembatasan, salah satu caranya adalah menggunakan columndan kemudian cut:

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

Tampaknya columnbukan POSIX. Ini adalah bagian dari utils BSD di Ubuntu, jadi saya menganggap itu adalah cross platform.


Menggunakan columncara ini OP bahkan tidak perlu menambahkan spasi secara manual untuk menyelaraskan.
Beni Cherniavsky-Paskin

1

Saran Don dalam komentar adalah awal yang baik.

Inilah yang saya butuhkan untuk membuatnya (kebanyakan) bekerja:

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

Itu -mdiperlukan untuk membuat -wbendera berlaku pada satu kolom. Halaman manual dapat menggunakan beberapa penulisan ulang untuk menunjukkan hal itu.

Ketika mencoba solusinya, saya menemukan bahwa prmenampilkan \tkarakter, jadi memberi makan hasilnya cutmenghasilkan masalah yang sama.

-1 (bendera kolom) secara khusus mengatakan di halaman manual:

Opsi ini tidak boleh digunakan dengan -m.

Namun, tanpa opsi ini prmemotong garis mau tak mau, jauh lebih pendek dari panjang yang ditentukan.

prjuga menyisipkan spasi sebelum (atau sesudah?) setiap kata dalam bidang (yaitu setiap tempat saya memiliki satu ruang, memiliki dua setelah pemrosesan). Jika ada terlalu banyak kata, spasi yang dimasukkan mengabaikan -wbatasan (membuat wrap-around). Tapi, anehnya, 'kolom' dibatasi-non-tab-dibatasi (yaitu spasi putih) tetap berbaris.



0

Satu utilitas yang harus benar-benar disadari oleh lebar layar adalah fold: sayangnya, sepertinya tidak memiliki opsi untuk membuang alih-alih membungkus. Meskipun mungkin sangat tidak efisien, namun Anda dapat melakukan sesuatu seperti

while read -r line; do fold -w80 <<< "$line" | head -n1; done < file
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.