Друкувати другий останній стовпчик / поле дивним способом


164

Я хочу надрукувати другий останній стовпчик або поле дивним способом. Кількість полів є змінною. Я знаю, що я повинен вміти користуватися, $NFале не знаю, як це можна використовувати.

І це, здається, не працює:

awk ' { print ( $NF-- )  } '

10
NFє останнім індексом поля, $NFце значення останнього поля
glenn jackman

це має сенс зараз. ось чому долар за межами дужок працює, я думаю
Брайан G

Відповіді:


279
awk '{print $(NF-1)}'

Треба працювати


2
Це не працює для мене. Я отримую "title: 5: команда не знайдена: NF-1" в awk 3.1.8 під Ubuntu.
Гурге

3
Я б уникнув
декрету

Ця awk -F '.' '{print $(NF-2)}'
помилка

3
@Gurgeh: Це трапляється тому, що $(..)викликає команду в нижній частині, залежно від оболонки, яку ви використовуєте. Ви можете обійти це, використовуючи $ (NF-1)замість цього $(NF-1).
Wting

21

Невелике доповнення до прийнятої відповіді Кріса Каннона: друкуйте лише тоді, коли насправді є другий останній стовпець.

(
echo       | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1     | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2   | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)

15

Це найпростіше:

 awk '{print $--NF}' 

Причина, по якій оригінал $NF--не спрацювала, полягає в тому, що вираз оцінюється перед декрементом, тоді як мій префікс виконується перед оцінкою.


Як мнемонічна така поведінка така сама, як C / Java тощо. int x = ++i int x = i++Префікс означає приріст спочатку; postfix означає приріст пізніше (присвоєння спочатку).
вихідні


4

Ви не були далеко від результату! Це робить це:

awk '{NF--; print $NF}' file

Це зменшує кількість полів в одному, так що $NFмістить колишню передостанню.

Тест

Створімо декілька чисел та роздрукуємо їх на групи по 5:

$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12

Давайте надрукуємо передостаннє в кожному рядку:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11

3

Рішення Perl, аналогічне дивним рішенням Кріса Каннона:

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

Ці параметри командного рядка використовуються:

  • n циклічно навколо кожного рядка вхідного файлу, не друкуйте кожен рядок автоматично

  • l видаляє нові рядки перед обробкою та додає їх згодом

  • aрежим автоспліт - розділити вхідні лінії в @Fмасив. За замовчуванням розділяється на пробіл

  • e виконати код Perl

@FМасив AutoSplit починається з індексу [0] в той час як поля AWK почати з $ 1.
$#F- кількість елементів у@F


1
або використовувати негативну індексацію, яку вже надає perl ...$F[-2]
Sundeep

2

Ви намагалися запустити справа наліво за допомогою команди rev? У цьому випадку вам просто потрібно роздрукувати другий стовпець:

seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11

1

Спочатку зменшується значення, а потім надрукується -

awk ' { print $(--NF)}' file

АБО

rev file|cut -d ' ' -f2|rev

0

Якщо у вас багато стовпців і ви хочете надрукувати всі, а не три стовпчики в останньому, то це може допомогти

awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.