Як надрукувати всі стовпці після певного числа за допомогою awk?


89

На оболонці я трублюся до awk, коли мені потрібна певна колонка.

Тут друкується стовпець 9, наприклад:

... | awk '{print $9}'

Як я можу сказати awk надрукувати всі стовпці, включаючи та після стовпця 9 , а не лише стовпець 9?


Відповіді:


82
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

3
кілька невеликих уточнень:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
Гленн Джекман

Дякую @glenn, це справді трохи загальніше. У будь-якому випадку - я б точно погодився, що було б краще використовувати cutабо perlдля цього. Використовуйте це, лише якщо ви справді наполягаєте на тому, щоб це було awk.
Амадан

1
@SiegeX: Він не додає байт NUL, він залишає FS на місці між кожним порожнім полем.
Призупинено до подальшого повідомлення.

1
Будь ласка, перегляньте відповідь @ Ascherer щодо елегантності.

3
@veryhungrymike: Елегантність - це приємно, але я волів би бути правильним. : p
Амадан

68

Коли ви хочете виконати ряд полів, awkнасправді немає прямого способу зробити це. cutНатомість я б рекомендував :

cut -d' ' -f 9- ./infile

Редагувати

Додано роздільник пробілу поля, оскільки за замовчуванням це вкладка. Дякую Гленну за те, що він вказав на це


15
Одна річ щодо вирізання полягає в тому, що він використовує певний роздільник (вкладка за замовчуванням), де awk використовує "пробіли". При вирізанні 2 послідовних вкладки обмежують порожнє поле.
glenn jackman

1
Як зазначив @glennjackman, роздільник awk - це "пробіли" (будь-яка сума теж). Отже, встановлення роздільника вирізу на одинарний пробіл також не відповідає поведінці. на жаль, петля - найкраще, що можна зробити, так це виглядає.
понча

Цей не працює належним чином. Спробуйте команду find . | xargs ls -l | cut -d' ' -f 9-. З якоїсь причини враховуються також подвійні пробіли. Приклад: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_bпризведе до./file_a 00:06 ./file_b
Марко Пашков

@MarcoPashkov прохання уточнити цей не працює належним чином , особливо з огляду на , що ви використовувати точний же код в трубопроводі. До речі, ви ніколи не
SiegeX

вирізати не робить тут роботи. Наприклад, якщо для одного рядка введено значення "foo bar" (одинарний пробіл), а для іншого "foo ___ bar" (тобто кілька пробілів, але SO занадто розумний, щоб це показати), вирізати їх буде по-іншому.
UKMonkey,

54
awk '{print substr($0, index($0,$9))}'

Редагувати : Зверніть увагу, це не працює, якщо будь-яке поле до дев'ятого містить те саме значення, що й дев'яте.


3
цей блискучий!

10
@veryhungrymike: ... і не працює, якщо будь-яке поле до дев'ятого містить те саме значення, що і дев'яте.
Амадан

6
Можливо, через класичне речення "сподіваємось, у вашому файлі немає цієї проблеми". Це загальне « ні-ні» в техніці з / у, щоб стверджувати: «ми не збираємося витрачати час, включаючи перевірку помилок на введення, наприклад, негативних значень, тому що« ми сподіваємось, що користувач буде достатньо розумним, щоб не випробувати їх, збій нашого інструменту '". ХАХАХА! Завжди люблю це чути! (Я як гарне почуття гумору) Ну, як ідіоти роблять існує, це обов'язок розробника , щоб зробити його речі дурня ! Замість "сподіватися на добро в людині". Це швидше таке ставлення, як очікується від філософів, а не інженерів-інженерів ... LOL
syntaxerror

3
Я не говорив, що не слід перевіряти наявність помилок, але якщо ви знаєте, що не збираєтеся стикатися з проблемою, то це рішення прекрасне, як я вже заявив. Але дякую вам за непотрібне голосування проти @syntaxerror. Це рішення буде працювати для деяких, як покаже (на даний момент) 19 голосів, але якщо ні, тоді не використовуйте його для свого рішення. Існує безліч способів вирішити проблему ОП.
Ascherer

1
Якщо ви використовуєте awk у командному рядку у своїй щоденній роботі, це точно рішення, яке ви хочете. Хіба це не очевидно? Перевірка помилок і т. Д. Насправді не має значення в цьому випадку, оскільки ви вводите її та можете вловити подібні речі перед тим, як натиснути клавішу Enter (особисто, я не думаю, що awk слід використовувати для чогось іншого, тому ми у мене є perl, python, tcl і близько 100+ інших, кращих, швидших, менш надокучливих мов сценаріїв!) 'Звичайно, я, можливо, даю своїм колегам-розробникам програмного забезпечення занадто багато кредитів, і вони дійсно потребують перевірки помилок навіть на тому, що вони вводять на льоту (??)
osirisgothra,

11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

Замість того, щоб мати справу з пробілами змінної ширини, замініть усі пробіли як єдиний пробіл. Тоді скористайтеся простим cutіз полями інтересу.

Він не використовує awk, тому не є загальним, але здається доречним з огляду на інші відповіді / коментарі.


1
Будь ласка, зробіть свою відповідь більш поглибленою, інакше опублікуйте це як коментар до питання.
Альпер Туран,

Це ідеально підходить для ps faux | використання. Ніколи не бійтеся визнати інструмент XYZ не найкращим.
kevinf

10

Зазвичай perl замінює awk / sed / grep et. та ін., і набагато портативніший (а також просто кращий ніж).

perl -lane 'print "@F[8..$#F]"'

Тімтовтді застосовується, звичайно.


Вам потрібно додати параметр командного рядка -lабо додати \nдо оператора друку.
glenn jackman

@glenn jackman: Можливо. Не потрібно, якщо частина іншого повідомлення або присвоєна змінній тощо. Що стосується "краще", perl, безумовно, виглядає краще в малому. Може зізнатися дуже неохайним у великому.
bobbogo

Не зрозумійте мене неправильно, мені подобається Perl. Я люблю awk за те, що це, хоча.
glenn jackman

Мій вбудований пристрій не постачається з Perl, але він має awk.
Sepero

Проголосування проти, тому що питання ставив, як це зробити в awk, а не perl, ruby, java, python, bash.
Том Гаррісон,

3
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

Це рубає те, що перед даним полем nr., N, і друкує всю решту рядка, включаючи поле nr.N та зберігаючи початковий інтервал (воно не переформатує). Не має значення, якщо рядок поля також з'являється десь ще в рядку, що є проблемою відповіді Ашерера.

Визначте функцію:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

І використовуйте його так:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

Вихідні дані підтримують все, включаючи кінцеві пробіли. Для N = 0 повертає весь рядок, як є, а для n> NF порожній рядок


Це гарна ідея. Це не зовсім працює на поточному Mac, використовуючи типовий gawk, тому що $ 0 падає. Виправлення полягає у встановленні змінної значення $ 0 як перший крок, наприклад: '{s = $ 0; ... print substr (s, index (s, m) +1}
joelparkerhenderson

1

Ось приклад ls -lрезультату:

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

Моє рішення надрукувати що-небудь повідомлення $9-awk '{print substr($0, 61, 50)}'



0

Для відображення перших 3 полів та роздрукування решти полів можна використовувати:

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

де $ 1 $ 2 $ 3 - це перші 3 поля.


0
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
}

0

Використання вирізання замість awk та подолання проблем із з’ясуванням, з якого стовпця починати, за допомогою команди -c вирізання символів.

Тут я кажу: дайте мені всі, крім перших 49 символів результату.

 ls -l /some/path/*/* | cut -c 50-

У /*/*/кінці команди ls сказано показати мені, що теж є в підкаталогах.

Ви також можете витягнути певні діапазони символів ala (зі сторінки вирізаного керівника). Наприклад, покажіть імена та час входу користувачів, які зараз ввійшли до системи:

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