Bagaimana cara saya menggunakan cut untuk memisahkan dengan banyak spasi putih?


23

Saya ingin mendapatkan kolom terakhir dari sampel ini:

[  3]  1.0- 2.0 sec  1.00 MBytes  8.39 Mbits/sec
[  3]  2.0- 3.0 sec   768 KBytes  6.29 Mbits/sec
[  3]  3.0- 4.0 sec   512 KBytes  4.19 Mbits/sec
[  3]  4.0- 5.0 sec   256 KBytes  2.10 Mbits/sec
...

Jika saya gunakan

cut -d\  -f 13

saya mendapat

Mbits/sec
6.29
4.19
2.10

karena terkadang ada ruang tambahan di antaranya.


Kolom terakhir adalah Mbits/sec, apakah itu yang Anda inginkan atau 2 kolom terakhir?
terdon

1
Saya hanya ingin mendapatkan kolom terakhir ke-2, hanya angka
rubo77

Jawaban:


17

Untuk menjawab pertanyaan Anda secara harfiah:

sed 's/   */:/g' | cut -d : -f 5

atau

awk -F '  +' '{print $5}'

Tapi itu tidak akan berhasil jika angka dalam kurung mencapai 10, dll. Jika Anda hanya tertarik pada angka, Anda bisa menghapus yang lainnya.

sed 's/[^.0-9][^.0-9]*/:/g' | cut -d : -f 6

ya, tentu saja angkanya, tetapi hanya contoh ke-3 Anda yang bekerja dengan benar
rubo77

@ rubo77 Bekerja untuk saya. Dua contoh pertama melakukan persis apa yang Anda minta pada judul Anda. Atau apakah Anda ingin melepas unit juga? Dalam hal itu, tambahkan | sed 's/ .*//'pada akhir dua contoh pertama. Tentu saja ada banyak cara lain untuk melakukannya.
Gilles 'SO- berhenti bersikap jahat'

sedikit lebih pendek dengan +bukannya *: tes kucing | sed 's / [^. 0-9] \ + /: / g' | cut -d: -f 6
rubo77

@ rubo77 Jika sed Anda mendukungnya, yaitu. Ini didukung oleh GNU dan BusyBox tetapi tidak oleh misalnya BSD atau Solaris. POSIX menentukan +dan ?dalam ERE tetapi tidak meninggalkan \+dan \?dalam BRE.
Gilles 'SANGAT berhenti menjadi jahat'

22

Jika kita menggunakan trperintah bersama dengan opsi pemerasan ( -sbendera) untuk mengonversi semua beberapa ruang berurutan menjadi satu ruang dan kemudian melakukan cutoperasi dengan ruang sebagai pembatas - kita dapat mengakses kolom yang diperlukan yang memuat angka-angka.

Lihat kode yang terpotong di bawah ini:

cat file | tr -s ' ' | cut -d ' ' -f 8


4
Jawaban ini harus lebih tinggi; ini jauh solusi yang paling sederhana dan paling mudah dibaca.
Luke Davis

5

Semua perintah ini akan mencetak kolom terakhir dari file yang dipisahkan oleh spasi:

  • awk '{print $NF}' file

    di awk, NFadalah jumlah bidang dan bidang $NFterakhir.

  • perl -lane 'print $F[$#F]' file

    -amembagi file pada spasi putih ke dalam array @F,$#F adalah jumlah elemen dalam array sehingga $F[$#F]merupakan elemen terakhir. Cara -nmembaca file yang diberikan pada baris perintah dan menerapkan skrip yang diteruskan -eke setiap baris. -lcukup tambahkan karakter baris baru ( \n) ke setiap printpernyataan.

  • sed 's/.* //g'

    ekspresi reguler sederhana yang cocok dengan semuanya hingga ruang terakhir dan menghapusnya, hanya menyisakan kolom terakhir.

  • rev file | cut -d' ' -f 1 | rev

    revmembalikkan outputnya sehingga bidang terakhir adalah yang pertama, cutdengan ruang pembatas untuk mencetaknya dan revmembalikkan teks kembali ke normal. Ini tidak akan berfungsi jika Anda memiliki spasi putih berturut-turut .

Berdasarkan input Anda, saya kira Anda tidak benar-benar menginginkan kolom terakhir tetapi yang kedua dari belakang atau dua yang terakhir. Dalam hal ini gunakan ini untuk mencetak 2 terakhir ( 8.39 Mbits/sec):

awk '{print $(NF-1),$NF}' file 
perl -lane 'print "$F[$#F-1] $F[$#F]"' file 
sed 's/.* \(.* .*\)/\1/' file 
rev file | cut -d' ' -f 1,2 | rev

dan ini untuk mencetak kedua dari belakang ( 8.39):

awk '{print $(NF-1)}' file 
perl -lane 'print $F[$#F-1]' file 
sed 's/.* \(.*\) .*/\1/' file 
rev file | cut -d' ' -f 2 | rev

4

Anda tidak dapat memisahkan beberapa kejadian spasi putih menggunakan cutsesuai manual:

Bidang output dipisahkan oleh kemunculan tunggal karakter pembatas bidang.

kecuali teks dipisahkan dengan jumlah yang sama atau Anda gunakan tr untuk menghapus kelebihannya.

Kalau tidak gunakan alat alternatif seperti awk,sed atauex .

Sebagai contoh:

ex -s +'%norm $2Bd0' +%p +q! foo.txt

Ganti +q!dengan -cwquntuk menyimpan perubahan di tempat.


0

Gunakan perl one-liner seperti:

perl -lane 'print $F[-2]' input_file

Penjelasan:

Pilihan -e menyebabkan penerjemah perl mencari skrip inline, bukan dalam file.

Pilihan -n menyebabkan input (file atau STDIN dari pipa) dibaca baris demi baris.

Pilihan -l menghapus pemisah rekaman input (tergantung OS, baris baru pada UNIX secara default) setelah membaca baris, dan menambahkannya di akhir setiapprint

Opsi -amenyebabkan setiap baris input dipecah pada spasi menjadi array @F, dan $F[-2]merupakan elemen kedua yang dihitung dari ujung, yang merupakan bidang yang Anda inginkan. Anda juga dapat menggunakan $F[$#F-1], di mana $#Findeks terakhir array @F, yang sedikit kurang dapat dibaca.

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.