Awk kullanarak son iki sütun nasıl yazdırılır


106

Tek istediğim yazdırılan son iki sütun.


6
Bunun neden 87 ek oyu olduğundan tam olarak emin değilim, en azından bir örnekle kesinlikle geliştirilebilir.
Arj

Muhtemelen sorunun doğası gereği son derece basit olması ve örnek olmadan kolayca anlaşılması nedeniyle, ki bu nadirdir, ancak bu durumda işe yarıyor gibi görünüyor. Buradaki sorun, bence bilgi eksikliği değil, daha çok bağımsız araştırma eksikliğini göstermesidir.
DryLabRebel

Bu soru aynı zamanda bu sorunun bir kopyasıdır .
DryLabRebel

Bu sorunuzu yanıtlıyor mu?
Awk'de

Yanıtlar:


194

NFGiriş kaydındaki toplam alan sayısına ayarlanmış değişkeni kullanabilirsiniz :

awk '{print $(NF-1),"\t",$NF}' file

bu, en az 2 alanınız olduğunu varsayar.


1
Virgül kullanmanız gerekir - bugün seçici olduğumuz için: boşluk alanları birleştirir, virgül bir print deyimindeki alanları ayırır. Bu iki alanı birleştirecek
jim mcnamara

18
Şimdi "field-OFS-tab-OFS-field" yazdırıyorsunuz. awk '{print $(NF-1) "\t" $NF}' fileVeya awk '{print $(NF-1), $NF}' fileveya olmalıdır awk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file.
sonraki duyuruya kadar duraklatıldı.

Sadece önceki yoruma eklemek için, kullanımla ilgili sorun '{print $x,"\t",$y}', awk'ın virgülle ayrılmış her değişkeni kendi alanı olarak yorumlamasıdır, bu nedenle sonuç gerçekte olacaktır field1<space><tab><space>field2(çünkü varsayılan olarak beyaz boşluk sınırlayıcı kullanacaktır) field1<tab>field2, muhtemelen hangisidir? bekliyorsun. Çıktı Alanı Ayırıcısı (OFS) kullanmak neredeyse her zaman istediğiniz şeydir.
DryLabRebel

13
awk '{print $NF-1, $NF}'  inputfile

Not: Bu, yalnızca en az iki sütun varsa çalışır. Tek sütunlu kayıtlarda sahte bir"-1 column1"


3
Deneyin ve görün. Solaris 9 awk & nawk çalışıyor. Alternatif $ (NF-1)
jim mcnamara

1
@coaddict - Farklı awk uygulamalarıyla çalışmadığınızı tahmin ediyorum. Eski garip davranışlar (belki de hatalı olarak) öne çıkarıldı. Test etmek için gawk yapmıyorum - muhtemelen bundan bahsediyorsunuz. Bu yüzden yorumunuzun neden anormal geldiğinden emin değilim. Kutudan çıkan Linux awk genellikle gawk'tır. Test edip geri göndereceğim. Bu arada eski awk ile ne demek istediğimi görmek için Soalris veya HPUX veya DGX veya her neyse deneyin.
jim mcnamara

6
Muhtemelen denediğin için işe yaradığını düşünmek için kandırıldın echo 1 2 3 | awk .... $NF-1olduğu ($NF) - 1her awkuygulanmasına.
Stephane Chazelas

"One True Awk" kaynak kodunun yaccdilbilgisinde 40'tan fazla çelişki vardır , bu da A'nın awk cinsinden ifade ettiği şey düşünüldüğünde ironiktir. Her şeyi farklı şekilde ayrıştıran awk'ın farklı sürümleri? Büyük sürpriz!
Kaz

1
@THESorcerer, ile deneyin echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'- veya son 2. alanın son alandan daha az olmadığı başka herhangi bir girdi.
glenn jackman

6

@jim mcnamara: etrafında parantez kullanmayı deneyin NF, yani $(NF-1)ve $(NF)yerine $NF-1ve $NF(FreeBSD için Mac OS X 10.6.8'de çalışır awkve gawk).

echo '
1 2
2 3
one
one two three
' | gawk '{if (NF >= 2) print $(NF-1), $(NF);}'

# output:
# 1 2
# 2 3
# two three

() Öğesini daha önce düşünmüştük. Orijinal eski awk davranışının nereden geldiğini tartıştığımızı sanıyordum.
jim mcnamara

Açık $(NF-1)olan bir cevap için +1 - en azından $NF-1; kesinlikle daha az belirsiz. $(NF)ama aşırıdır - sadece $NFyapacak. Tek sütunlu satırlarda ilk sütun değerini iki kez elde edeceğiniz ve sıfır sütun - yani boş - satırlarda awk komutu bir girişim nedeniyle tamamen başarısız olacağı için, 2'den az sütunlu satırlara karşı koruma sağlamak da faydalıdır. -1 indeksi olan bir alana erişmek için.
mklement0

1

gawk kullanmak sorunu gösterir:

 gawk '{ print $NF-1, $NF}' filename
1 2
2 3
-1 one
-1 three
# cat filename
1 2
2 3
one
one two three

Solaris 10 M4000'e gawk koydum: Yani, gawk, $ NF-1'e karşı $ (NF-1) sorununun kupasıdır. Sonraki soru POSIX ne diyor? başına:

http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html

Öyle ya da böyle bir yön yok. İyi değil. gawk çıkarma anlamına gelir, diğer awks ise alan numarası veya çıkarma anlamına gelir. hmm.


1
Örnek girdi dosyanızın ilk 2 satırı, her iki davranışla aynı çıktıyı ürettikleri için yardımcı olmaz . Bu durumda Solaris awk'nin gerçekten de gawk gibi davranmadığını tekrar teyit edebilir misiniz?
mklement0

Awk spesifikasyonuna olan bağlantınıza gelince: Kullanılacak anekdot argümanı $(NF-1), spesifikasyondaki alan indeksini hesaplamanın iki örneğinin her ikisinin de şu formu kullanmasıdır: $(NF-1)ve $(NF+2). Sonra, $expr[çok] daha yüksek önceliğe sahip olarak listeleyen "awk içindeki ifadeler" bölümü var expr - expr. Bu yana NFbir ekspresyon kendisi, $NF-1hiç değerlendirmelidir ($NF)-1. Sonuçta, orada bile, EĞER gerçekten değerlendirmek orada uygulamaları awk $NF-1olarak $(NF-1), ders burada öğrendim kullanarak olmasıdır $(NF-1)güvenli ve taşınabilir bir seçimdir.
mklement0

0

bununla dene

$ cat /tmp/topfs.txt
/dev/sda2      xfs        32G   10G   22G  32% /

awk print last column
$ cat /tmp/topfs.txt | awk '{print $NF}'

awk print before last column
$ cat /tmp/topfs.txt | awk '{print $(NF-1)}'
32%

awk - print last two columns
$ cat /tmp/topfs.txt | awk '{print $(NF-1), $NF}'
32% /

0

Lütfen tüm olası senaryoları hesaba katmak için bunu deneyin:

awk '{print $(NF-1)"\t"$NF}'  file

veya

awk 'BEGIN{OFS="\t"}' file

veya

awk '{print $(NF-1), $NF} {print $(NF-1), $NF}' file
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.