beberapa perbaikan kecil:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman
Terima kasih @glenn, itu memang sedikit lebih umum. Bagaimanapun - saya pasti setuju akan lebih baik menggunakan cutatau perluntuk ini. Gunakan ini hanya jika Anda benar-benar bersikeras untuk memilikinya awk.
Amadan
1
@SiegeX: Ini tidak menambahkan byte NUL, meninggalkan FS di antara setiap bidang kosong.
Dijeda sampai pemberitahuan lebih lanjut.
1
Silakan lihat jawaban @ Ascherer untuk keanggunan.
3
@veryhungrymike: Keanggunan itu bagus, tapi saya lebih suka benar. : p
Amadan
68
Ketika Anda ingin melakukan berbagai bidang, awktidak benar-benar memiliki cara langsung untuk melakukan ini. Saya akan merekomendasikan cutsebagai gantinya:
cut -d' ' -f 9- ./infile
Edit
Menambahkan pembatas bidang spasi karena defaultnya adalah tab. Terima kasih kepada Glenn karena telah menunjukkan hal ini
Satu hal tentang cut adalah bahwa ia menggunakan pembatas tertentu (tab secara default), di mana awk menggunakan "spasi". Dengan pemotongan, 2 tab berturut-turut membatasi bidang kosong.
glenn jackman
1
Seperti yang ditunjukkan @glennjackman, pembatas awk adalah "spasi" (berapa pun jumlahnya). Jadi, menyetel pembatas potong ke satu spasi tidak akan cocok dengan perilaku juga. sayangnya loop adalah yang terbaik yang bisa dilakukan, jadi sepertinya.
poncha
Yang ini tidak berfungsi dengan baik. Coba perintahnya find . | xargs ls -l | cut -d' ' -f 9-. Untuk beberapa alasan spasi ganda juga dihitung. Contoh: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_bakan menghasilkan./file_a 00:06 ./file_b
Marco Pashkov
@MarcoPashkov harap jelaskan Hal ini tidak berfungsi dengan baik , terutama mengingat Anda menggunakan kode yang sama persis di pipeline Anda. Omong-omong, Anda tidak
SiegeX
cut tidak melakukan pekerjaan di sini. Misalnya, jika input Anda adalah "foo bar" (spasi tunggal) untuk satu baris, dan "foo ___ bar" (yaitu beberapa spasi, tetapi SO terlalu pintar untuk menampilkannya) untuk baris lainnya, cut akan memprosesnya secara berbeda.
UKMonkey
54
awk '{print substr($0, index($0,$9))}'
Edit : Perhatikan, ini tidak berfungsi jika ada bidang sebelum yang kesembilan berisi nilai yang sama dengan yang kesembilan.
@veryhungrymike: ... dan tidak berfungsi jika ada bidang sebelum kesembilan berisi nilai yang sama dengan yang kesembilan.
Amadan
6
Mungkin karena kalimat klasik "semoga file Anda tidak mengalami masalah itu". Ini adalah total no-no in s / w engineering untuk menyatakan: "kami tidak akan membuang waktu termasuk pengecekan kesalahan untuk masukan misalnya nilai negatif, karena 'kami berharap pengguna akan cukup cerdas untuk tidak mencobanya, merusak alat kami '". HA HA HA! Selalu senang mendengar ini! (Saya suka selera humor yang bagus) Yah, karena orang idiot memang ada, itu adalah tugas pengembang untuk membuat barang-barangnya tahan terhadap orang bodoh ! Dari pada "mengharapkan kebaikan dalam diri manusia". Itu lebih merupakan sikap yang diharapkan oleh para filsuf, bukan para insinyur ... LOL
kesalahan sintaksis
3
Saya tidak mengatakan untuk tidak memeriksa kesalahan, tetapi jika Anda tahu Anda tidak akan mengalami masalah, maka solusi ini baik-baik saja, seperti yang saya nyatakan. Tapi terima kasih atas downvote @syntaxerror yang tidak perlu. Solusi ini akan berfungsi untuk beberapa orang, karena (saat ini) 19 suara positif akan ditampilkan, tetapi jika tidak, jangan gunakan untuk solusi Anda. Ada banyak cara untuk mengatasi masalah OP.
Ascherer
1
Jika Anda menggunakan awk pada baris perintah dalam pekerjaan sehari-hari Anda, ini jelas merupakan solusi yang Anda inginkan. Apakah tidak jelas? Pemeriksaan kesalahan, dll, tidak terlalu penting dalam hal itu karena Anda mengetiknya & dapat menangkap hal-hal semacam ini sebelum Anda menekan enter (secara pribadi, saya tidak berpikir awk harus digunakan untuk hal lain, itu sebabnya kami Saya punya perl, python, tcl, dan sekitar 100+ bahasa skrip lainnya, lebih baik, lebih cepat, dan tidak terlalu mengganggu!) 'Tentu saja mungkin saya memberi kredit terlalu banyak kepada sesama pengembang perangkat lunak dan mereka benar-benar membutuhkan pemeriksaan kesalahan bahkan pada hal-hal yang mereka ketik dengan cepat (??)
osirisgothra
11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-
Alih-alih berurusan dengan spasi putih lebar variabel, ganti semua spasi putih sebagai spasi tunggal. Kemudian gunakan sederhana cutdengan bidang yang diminati.
Itu tidak menggunakan awk jadi tidak erat tetapi sepertinya sesuai diberikan jawaban / komentar lain.
Anda perlu menambahkan opsi baris perintah -l, atau menambahkan \nke pernyataan cetak.
glenn jackman
@ Glenn Jackman: Mungkin. Tidak diperlukan jika bagian dari pesan lain, atau ditugaskan ke variabel dll. Sejauh "lebih baik" berjalan, perl pasti terlihat lebih baik di yang kecil. Bisa terlihat sangat tidak rapi di tempat yang besar memang.
bobbogo
Jangan salah paham, saya suka Perl. Aku suka canggung untuk apa adanya.
glenn jackman
Perangkat saya yang disematkan tidak disertakan dengan Perl, tetapi memiliki awk.
Sepero
Downvoting karena pertanyaannya menanyakan bagaimana melakukan ini di awk, bukan perl, ruby, java, python, bash.
Ini memotong apa yang ada sebelum bidang yang diberikan nr., N, dan mencetak semua sisa baris, termasuk bidang nr.N dan mempertahankan jarak asli (tidak memformat ulang). Tidak masalah jika string bidang muncul juga di tempat lain dalam baris, yang merupakan masalah dengan jawaban Ascherer.
Ini ide yang bagus. Itu tidak cukup berfungsi pada Mac saat ini menggunakan gawk biasa, karena $ 0 runtuh. Cara memperbaikinya adalah menyetel variabel ke $ 0 sebagai langkah pertama, seperti: '{s = $ 0; ... cetak substr (s, indeks (s, m) +1}
Menggunakan cut daripada awk dan mengatasi masalah dengan mencari tahu kolom mana untuk memulai dengan menggunakan perintah -c character cut.
Di sini saya katakan, berikan semua kecuali 49 karakter pertama dari keluaran.
ls -l /some/path/*/* | cut -c 50-
Itu /*/*/ akhir perintah ls mengatakan tunjukkan apa yang ada di subdirektori juga.
Anda juga dapat menarik rentang karakter tertentu secara (dari halaman manual yang dipotong). Misalnya, tunjukkan nama dan waktu login dari pengguna yang sedang login:
Jawaban:
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'
sumber
awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
cut
atauperl
untuk ini. Gunakan ini hanya jika Anda benar-benar bersikeras untuk memilikinyaawk
.Ketika Anda ingin melakukan berbagai bidang,
awk
tidak benar-benar memiliki cara langsung untuk melakukan ini. Saya akan merekomendasikancut
sebagai gantinya:cut -d' ' -f 9- ./infile
Edit
Menambahkan pembatas bidang spasi karena defaultnya adalah tab. Terima kasih kepada Glenn karena telah menunjukkan hal ini
sumber
find . | xargs ls -l | cut -d' ' -f 9-
. Untuk beberapa alasan spasi ganda juga dihitung. Contoh:lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_b
akan menghasilkan./file_a 00:06 ./file_b
awk '{print substr($0, index($0,$9))}'
Edit : Perhatikan, ini tidak berfungsi jika ada bidang sebelum yang kesembilan berisi nilai yang sama dengan yang kesembilan.
sumber
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-
Alih-alih berurusan dengan spasi putih lebar variabel, ganti semua spasi putih sebagai spasi tunggal. Kemudian gunakan sederhana
cut
dengan bidang yang diminati.Itu tidak menggunakan awk jadi tidak erat tetapi sepertinya sesuai diberikan jawaban / komentar lain.
sumber
ps faux |
digunakan. Jangan pernah takut mengakui alat XYZ bukan yang paling tepat.Umumnya perl menggantikan awk / sed / grep et. al., dan banyak lebih portabel (serta menjadi pisau lipat yang lebih baik).
perl -lane 'print "@F[8..$#F]"'
Timtowtdi berlaku tentu saja.
sumber
-l
, atau menambahkan\n
ke pernyataan cetak.awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'
Ini memotong apa yang ada sebelum bidang yang diberikan nr., N, dan mencetak semua sisa baris, termasuk bidang nr.N dan mempertahankan jarak asli (tidak memformat ulang). Tidak masalah jika string bidang muncul juga di tempat lain dalam baris, yang merupakan masalah dengan jawaban Ascherer.
Tentukan fungsi:
fromField () { awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}' }
Dan gunakan seperti ini:
$ echo " bat bi iru lau bost " | fromField 3 iru lau bost $ echo " bat bi iru lau bost " | fromField 2 bi iru lau bost
Output mempertahankan semuanya, termasuk spasi tambahan Untuk N = 0 ia mengembalikan seluruh baris, sebagaimana adanya, dan untuk n> NF string kosong
sumber
Berikut adalah contoh
ls -l
keluarannya:Solusi saya untuk mencetak postingan apa pun
$9
adalahawk '{print substr($0, 61, 50)}'
sumber
ruby -lane 'print $F[3..-1].join(" ")' file
sumber
Untuk menampilkan 3 kolom pertama dan mencetak kolom lainnya, Anda dapat menggunakan:
awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename
di mana $ 1 $ 2 $ 3 adalah 3 bidang pertama.
sumber
function print_fields(field_num1, field_num2){ input_line = $0 j = 1; for (i=field_num1; i <= field_num2; i++){ $(j++) = $(i); } NF = field_num2 - field_num1 + 1; print $0 $0 = input_line }
sumber
Menggunakan cut daripada awk dan mengatasi masalah dengan mencari tahu kolom mana untuk memulai dengan menggunakan perintah -c character cut.
Di sini saya katakan, berikan semua kecuali 49 karakter pertama dari keluaran.
Itu
/*/*/
akhir perintah ls mengatakan tunjukkan apa yang ada di subdirektori juga.Anda juga dapat menarik rentang karakter tertentu secara (dari halaman manual yang dipotong). Misalnya, tunjukkan nama dan waktu login dari pengguna yang sedang login:
sumber