Baris ini bekerja sampai saya memiliki spasi putih di bidang kedua.
svn status | grep '\!' | gawk '{print $2;}' > removedProjs
adakah cara untuk mencetak semuanya dalam $ 2 atau lebih? ($ 3, $ 4 .. sampai kita tidak memiliki kolom lagi?)
Saya kira saya harus menambahkan bahwa saya melakukan ini di lingkungan Windows dengan Cygwin.
grep | awk
ini adalah antipattern - Anda inginkanawk '/!/ { print $2 }'
svn status | grep '\!' | cut -d' ' -f2- > removedProjs
Jawaban:
akan mencetak semua kecuali kolom pertama:
akan mencetak semua kecuali dua kolom pertama:
sumber
awk '{$1=""; print substr($0,2)}' input_filename > output_filename
awk -F, -vOFS=, '{$1=""; print $0}'
Anda akan berakhir dengan pembatas awal ($1
masih termasuk, seperti string kosong). Anda dapat menghapusnya dengansed
:awk -F, -vOFS=, '{$1=""; print $0}' | sed 's/^,//'
Ada pertanyaan duplikat dengan jawaban sederhana menggunakan cut:
-d
menentukan delimeter (spasi) ,-f
menentukan daftar kolom (semua dimulai dengan ke-2)sumber
awk
versi, ada masalah buffering baris dengancut
, yangawk
tidak memiliki: stackoverflow.com/questions/14360640/…awk
memperlakukan beberapa karakter ruang yang berdekatan. sebagai pemisah tunggal , sementaracut
tidak; juga - meskipun ini bukan masalah dalam kasus yang dihadapi -cut
hanya menerima satu, karakter literal. sebagai pembatas, sedangkanawk
memungkinkan regex.Anda bisa menggunakan for-loop untuk mengulang melalui bidang pencetakan $ 2 hingga $ NF (variabel bawaan yang mewakili jumlah bidang pada baris).
Sunting: Karena "print" menambahkan baris baru, Anda ingin buffer hasilnya:
Atau, gunakan printf:
sumber
'{for(i=11;i<=NF-1;i++){printf "%s ", $i}; print $NF;}'
Tidak ada ruang depan atau belakang.Jawaban saya didasarkan pada salah satu VeeArr , tetapi saya perhatikan itu dimulai dengan spasi putih sebelum akan mencetak kolom kedua (dan sisanya). Karena saya hanya memiliki 1 poin reputasi, saya tidak dapat mengomentarinya, jadi ini dia sebagai jawaban baru:
mulai dengan "keluar" sebagai kolom kedua dan kemudian tambahkan semua kolom lainnya (jika ada). Ini berjalan dengan baik selama ada kolom kedua.
sumber
Sebagian besar solusi dengan awk menyisakan ruang. Opsi di sini menghindari masalah itu.
Pilihan 1
Solusi pemotongan sederhana (hanya bekerja dengan pembatas tunggal):
pilihan 2
Memaksa re-cal awk kadang-kadang menghapus ruang pimpinan tambahan (OFS) yang tersisa dengan menghapus kolom pertama (berfungsi dengan beberapa versi awk):
Opsi 3
Mencetak setiap bidang yang diformat dengan
printf
akan memberikan kontrol lebih besar:Namun, semua jawaban sebelumnya mengubah semua FS berulang antara bidang menjadi OFS. Mari kita membangun beberapa opsi yang tidak melakukannya.
Opsi 4 (disarankan)
Lingkaran dengan sub untuk menghapus bidang dan pembatas di bagian depan.
Dan menggunakan nilai FS bukan ruang (yang bisa diubah).
Lebih portabel, dan tidak memicu perubahan FS ke OFS: CATATAN: The
^[FS]*
adalah menerima masukan dengan spasi terkemuka.Opsi 5
Sangat mungkin untuk membangun solusi yang tidak menambahkan spasi putih tambahan (memimpin atau mengikuti), dan melestarikan spasi putih yang ada menggunakan fungsi
gensub
dari GNU awk, karena ini:Itu juga dapat digunakan untuk menukar sekelompok bidang yang diberi hitungan
n
:Tentu saja, dalam kasus seperti itu, OFS digunakan untuk memisahkan kedua bagian dari garis, dan ruang putih trailing bidang masih dicetak.
CATATAN:
[FS]*
digunakan untuk memungkinkan spasi di baris input.sumber
Saya pribadi mencoba semua jawaban yang disebutkan di atas, tetapi kebanyakan dari mereka agak rumit atau tidak tepat. Cara termudah untuk melakukannya dari sudut pandang saya adalah:
Di mana -F "" mendefinisikan pembatas untuk awk untuk digunakan. Dalam kasus saya adalah spasi putih, yang juga merupakan pembatas default untuk awk. Ini berarti bahwa "" F dapat diabaikan.
Di mana NF menentukan jumlah total bidang / kolom. Oleh karena itu loop akan dimulai dari bidang ke-4 hingga ke bidang / kolom terakhir.
Di mana $ N mengambil nilai bidang Nth. Oleh karena itu cetak $ i akan mencetak bidang / kolom saat ini berdasarkan pada jumlah loop.
sumber
lauhub mengusulkan solusi yang benar, sederhana, dan cepat ini di sini
sumber
Ini sangat menjengkelkan saya, saya duduk dan menulis
cut
parser spesifikasi lapangan seperti, diuji dengan GNU Awk 3.1.7.Pertama, buat skrip library Awk baru bernama
pfcut
, dengan egLalu, rekatkan skrip di bawah ini, dan simpan. Setelah itu, begini tampilannya:
Untuk menghindari mengetik semua itu, saya kira yang terbaik bisa dilakukan (lihat sebaliknya Secara otomatis memuat fungsi pengguna saat startup dengan awk? - Unix & Linux Stack Exchange ) adalah menambahkan alias ke
~/.bashrc
; misalnya dengan:... maka Anda bisa langsung menelepon:
Inilah sumber
pfcut
naskahnya:sumber
cut
, bukanawk
Mencetak kolom mulai dari # 2 (output tidak akan memiliki ruang tambahan di awal):
sumber
+
setelah spasi, karena bidang dapat dipisahkan oleh lebih dari 1 ruang (awk
memperlakukan beberapa ruang yang berdekatan sebagai pemisah tunggal). Juga,awk
akan mengabaikan spasi awal, jadi Anda harus memulai regex dengan^[ ]*
. Dengan ruang sebagai pemisah Anda bahkan bisa menggeneralisasi solusi; misalnya, yang berikut mengembalikan semuanya dari bidang ke-3:awk '{sub(/^[ ]*([^ ]+ +){2}/, ""); print $0}'
Namun, hal itu akan semakin rumit dengan pemisah bidang yang sewenang-wenang.Apakah ini akan berhasil?
Itu meninggalkan beberapa spasi di depan.
sumber
yang ini menggunakan awk untuk mencetak semua kecuali kolom terakhir
sumber
Inilah yang saya sukai dari semua rekomendasi:
Mencetak dari kolom ke-6 hingga terakhir.
atau
sumber
Jika Anda membutuhkan kolom tertentu yang dicetak dengan delimeter acak:
Jadi, jika Anda memiliki spasi dalam kolom itu akan menjadi dua kolom, tetapi Anda dapat menghubungkannya dengan pembatas apa pun atau tanpa itu.
sumber
Solusi Perl:
Opsi baris perintah ini digunakan:
-n
lingkaran di sekitar setiap baris dari file input, jangan otomatis mencetak setiap baris-l
menghapus baris baru sebelum diproses, dan menambahkannya kembali sesudahnya-a
mode autosplit - membagi jalur input ke dalam array @F. Default untuk memisahkan di spasi putih-e
jalankan kode perlsplice @F,0,1
menghapus kolom 0 dari array @F dengan bersihjoin " ",@F
bergabung dengan elemen-elemen dari array @F, menggunakan spasi di antara setiap elemenSolusi Python:
python -c "import sys;[sys.stdout.write(' '.join(line.split()[1:]) + '\n') for line in sys.stdin]" < file
sumber
Jika Anda tidak ingin memformat ulang bagian dari baris yang tidak Anda potong, solusi terbaik yang dapat saya pikirkan tertulis dalam jawaban saya di:
Bagaimana cara mencetak semua kolom setelah nomor tertentu menggunakan awk?
Ini memotong apa yang sebelum nomor bidang yang diberikan N, dan mencetak semua sisa baris, termasuk nomor bidang N dan mempertahankan spasi asli (tidak memformat ulang). Itu tidak mater jika string bidang muncul juga di tempat lain di baris.
Tentukan fungsi:
Dan gunakan seperti ini:
Keluaran memelihara segalanya, termasuk spasi tambahan
Dalam kasus khusus Anda:
Jika file / stream Anda tidak mengandung karakter baris baru di tengah-tengah baris (Anda bisa menggunakan Pemisah Catatan yang berbeda), Anda dapat menggunakan:
Kasus pertama akan gagal hanya dalam file / stream yang berisi karakter nomor 1 langka hexadecimal
sumber
Ini akan berfungsi jika Anda menggunakan Bash dan Anda bisa menggunakan sebanyak 'x' sebagai elemen yang ingin Anda buang dan mengabaikan banyak ruang jika tidak diloloskan.
sumber
Perl:
sumber
awk
Fungsi ini mengembalikan substring$0
yang mencakup bidang daribegin
keend
:Untuk mendapatkan semuanya mulai dari bidang 3:
Untuk mendapatkan bagian
$0
yang mencakup bidang 3 hingga 5:b, e, p, i
omong kosong dalam daftar parameter fungsi hanyalahawk
cara mendeklarasikan variabel lokal.sumber
Saya ingin memperluas jawaban yang diusulkan untuk situasi di mana bidang dibatasi oleh beberapa spasi putih - alasan mengapa OP tidak menggunakan
cut
saya kira.Saya tahu OP bertanya
awk
, tetapised
pendekatan akan bekerja di sini (misalnya dengan mencetak kolom dari tanggal 5 hingga yang terakhir):pendekatan sed murni
Penjelasan:
s///
digunakan cara standar untuk melakukan substitusi^\s*
cocok dengan spasi putih berurutan di awal baris\S+\s+
berarti kolom data (karakter bukan spasi diikuti oleh karakter spasi)(){4}
berarti polanya diulang 4 kali.sed dan potong
dengan hanya mengganti spasi putih berurutan dengan satu tab;
tr and cut:
tr
juga dapat digunakan untuk memeras karakter berurutan dengan-s
opsi.sumber
Contoh awk terlihat rumit di sini, berikut adalah sintaks Bash shell sederhana:
Di mana kolom ke- n
1
Anda dihitung dari 0.Contoh
Mengingat konten file ini (
in.txt
):di sini adalah output:
sumber
Saya tidak senang dengan salah satu
awk
solusi yang disajikan di sini karena saya ingin mengekstrak beberapa kolom pertama dan kemudian mencetak sisanya, jadi saya beralih keperl
. Kode berikut mengekstrak dua kolom pertama, dan menampilkan sisanya seperti:Keuntungan dibandingkan dengan
perl
solusi dari Chris Koknat adalah benar-benar hanya elemen n pertama yang dipisahkan dari string input; sisa string tidak terpecah sama sekali dan karenanya tetap utuh sepenuhnya. Contoh saya menunjukkan ini dengan campuran spasi dan tab.Untuk mengubah jumlah kolom yang harus diekstraksi, ganti
3
dalam contoh dengan n +1.sumber
dari jawaban ini tidak buruk tetapi jarak alami hilang.
Silakan bandingkan dengan yang ini:
Maka Anda akan melihat perbedaannya.
Bahkan
ls -la | awk '{$1=$2=""; print}'
yang didasarkan pada jawaban sebagai yang terbaik sejauh ini tidak mempertahankan format.Jadi saya akan menggunakan yang berikut, dan juga memungkinkan kolom selektif eksplisit di awal:
Perhatikan bahwa setiap spasi juga dihitung untuk kolom, jadi misalnya di bawah ini, kolom 1 dan 3 kosong, 2 adalah INFO dan 4 adalah:
sumber
Jika Anda ingin teks yang diformat, rantai perintah Anda dengan gema dan gunakan $ 0 untuk mencetak bidang terakhir.
Contoh:
Cetakan:
sumber
Karena jawaban yang salah paling banyak dipilih dengan 340 suara, saya baru saja kehilangan 5 menit hidup saya! Adakah yang mencoba jawaban ini sebelum memperbaiki ini? Tampaknya tidak. Benar-benar tidak berguna.
Saya memiliki log di mana setelah $ 5 dengan alamat IP dapat lebih banyak teks atau tidak ada teks. Saya perlu semuanya, mulai dari alamat IP hingga akhir baris seandainya ada sesuatu setelah $ 5. Dalam kasus saya, ini sebenarnya bukan program awk, bukan onkiner awk jadi awk harus menyelesaikan masalah. Ketika saya mencoba untuk menghapus 4 bidang pertama menggunakan jawaban yang paling terbalik tetapi benar-benar salah:
itu mengeluarkan respons yang salah dan tidak berguna (saya menambahkan [..] untuk menunjukkan):
Bahkan ada beberapa saran untuk menggabungkan substrat dengan jawaban yang salah ini. Seperti itu komplikasi adalah perbaikan.
Sebaliknya, jika kolom adalah lebar tetap sampai titik potong dan awk diperlukan, jawaban yang benar adalah:
yang menghasilkan output yang diinginkan:
sumber