Как напечатать третий столбец до последнего столбца?

Я пытаюсь удалить первые два столбца (которые меня не интересуют) из файла журнала DbgView. Кажется, я не могу найти пример, который печатается от столбца 3 и далее до конца строки. Обратите внимание, что в каждой строке есть переменное количество столбцов.


person Amit G    schedule 21.10.2009    source источник
comment
возможный дубликат Использование awk для печати всего столбцы с n-го по последний   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 19.07.2015


Ответы (18)


... или более простое решение: cut -f 3- INPUTFILE просто добавьте правильный разделитель (-d), и вы получите тот же эффект.

person Marcin    schedule 21.10.2009
comment
Обратите внимание, что это работает только в том случае, если разделитель для всех столбцов точно такой же ... Например, вы не можете использовать вырезку с разделителем, например \ d +. (Это я знаю.) - person Zach Wily; 14.01.2010
comment
Когда вопрос озаглавлен awk, неуместно принимать ответ, отличный от awk. Что делать, если людям это нужно для сценариев awk? Этот ответ должен был быть просто комментарием. - person syaz; 01.11.2010
comment
@SyaZ: Обычно я бы согласился, но, учитывая количество «беспричинной awk» на этой доске, я подумал, что нужно показать альтернативный способ выполнения задачи. Разве вы не были бы благодарны, если бы кто-нибудь показал вам более простой и быстрый способ выполнить ту же задачу? Может быть, автор сообщения подумал, что awk - единственный способ сделать это из-за большого количества «не неверных, но, безусловно, улучшаемых» ответов на другие вопросы? - person Marcin; 01.11.2010
comment
Вот для чего нужен комментарий. Примите лучший ответ awk и предоставьте лучшие не-awk предложения по комментариям. Если люди начнут публиковать ответы, в которых нет точных ответов на вопросы, это будет раздражать при поиске (в моем случае). - person syaz; 02.11.2010
comment
Не только разделитель должен быть одинаковым для всех столбцов, но должен быть ТОЛЬКО ОДИН символ разделителя между столбцами. Поэтому, если вы имеете дело с программами, вывод которых выравнивается с помощью разделителей, лучше использовать awk. - person sknaumov; 21.08.2012
comment
зачем тебе тире после 3? - person vehomzzz; 15.10.2012
comment
3 само по себе является полем печати номер 3. 3- это поле печати 3 и все поля после него. - person Marcin; 16.10.2012
comment
@ZachWily, @sknaumov, способ Unix смягчить эту проблему с разделителем \ s + - заранее пропустить tr -s '[:blank:]' ' ' [источник]. - person K3---rnc; 31.07.2014
comment
Просто быстрое обновление, я запустил кучу awk-решений из этого потока, и все они работали немного около 65-78 секунд (файл 2,2 ГБ), в то время как моя простая «вырезанная» версия работала за 6 секунд. Я выигрываю ;) - person Marcin; 02.07.2015
comment
Перезапустите сценарии awk, используя mawk вместо gawk. Время работы 12-13сек. Cut по-прежнему выигрывает по скорости. - person Marcin; 02.07.2015
comment
Исходный заголовок запрашивал ответ с помощью Awk, поэтому по этой причине я согласен, что это не должно было быть отмечено галочкой. Однако я не считаю, что теги должны ограничивать ответы, поскольку часто спрашивающий просто догадывается, как пометить теги, чтобы заинтересованные люди посмотрели на их вопрос. Это не требование о том, как вы должны отвечать на вопрос. Вопрос в тех случаях, когда он устанавливает ограничение. - person Gerry; 15.12.2019

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

найденное здесь решение:
http://www.linuxquestions.org/questions/linux-newbie-8/awk-print-field-to-end-and-character-count-179078/

person daisaa    schedule 08.07.2011
comment
Я немного опоздал с этим, но это не сработает для записей, в которых первое или второе поле равно третьему (например, 3 2 3 4 5) - person aleph_null; 25.10.2011
comment
также возможна печать внутреннего диапазона: `` # от 3 долларов (включительно) до 6 долларов (исключая); эхо 1,2,3,4,5,6,7,8,9 | awk 'BEGIN {FS = ,; OFS =,} {print substr ($ 0, index ($ 0, $ 3), length ($ 0) -index ($ 0, $ 6) -1)}'; # дает 3,4,5 '' - person splaisan; 27.11.2019

В ответе Джонатана Файнберга каждое поле печатается в отдельной строке. Вы можете использовать printf, чтобы перестроить запись для вывода в той же строке, но вы также можете просто переместить поля прыжком влево.

awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile
person Dennis Williamson    schedule 21.10.2009
comment
Имейте в виду, что это работает только для Gnu awk, уменьшение NF не разрешено POSIX. - person kvantour; 04.01.2019
comment
@kvantour: Работает в gawk, mawk, MacOS awk (nawk?). POSIX, похоже, ничего не говорит о том, можно ли уменьшить NF. - person Dennis Williamson; 04.01.2019
comment
Это один из таких забавных темные уголки awk. - person kvantour; 04.01.2019

awk '{$1=$2=$3=""}1' file

NB: этот метод оставит «пробелы» в полях 1,2,3, но это не проблема, если вы просто хотите посмотреть вывод.

person ghostdog74    schedule 24.10.2009
comment
Отследите эту команду с помощью `| sed s / ^ \ * // | column -t`, чтобы удалить ведущие пробелы и выровнять оставшиеся столбцы - person MSpreij; 09.09.2014
comment
Что означает последний 1? по какому ключевому слову искать по awk? - person Itachi; 06.12.2018
comment
@Itachi см. Пример 1 catonmat.net/blog/awk -один-строчки-объяснение-часть-первая - person kvantour; 04.01.2019
comment
@Nathan, вы решаете эту проблему как {$1=$2=$3="";$0=$0;$1=$1}1 - person kvantour; 04.01.2019
comment
Это действительно полезно для отсеивания нескольких ненужных столбцов в середине (при этом до конца)! Спасибо @ ghostdog74 - person Erich; 21.09.2020

Если вы хотите напечатать столбцы после 3-го, например, в той же строке, вы можете использовать:

awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}'

Например:

Mar 09:39 20180301_123131.jpg
Mar 13:28 20180301_124304.jpg
Mar 13:35 20180301_124358.jpg
Feb 09:45 Cisco_WebEx_Add-On.dmg
Feb 12:49 Docker.dmg
Feb 09:04 Grammarly.dmg
Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf

Он напечатает:

20180301_123131.jpg
20180301_124304.jpg
20180301_124358.jpg
Cisco_WebEx_Add-On.dmg
Docker.dmg
Grammarly.dmg
Payslip 10459 %2828-02-2018%29.pdf

Как видим, расчетная ведомость даже с пробелом отображается в правильной строке.

person Brother    schedule 06.03.2018
comment
Это отлично, за исключением того, что у меня проблема с исключением $ NF. Когда я устанавливаю условие (‹= NF), я получаю последнее поле, но первый символ первого поля обрезается. Я что-то неправильно понимаю с точки зрения функциональности? - person Ken Ingram; 24.01.2020
comment
Похоже, моя проблема в том, что ^ M застрял в конце последнего столбца. Не вижу, как его удалить. - person Ken Ingram; 24.01.2020

А как насчет следующей строки:

awk '{$1=$2=$3=""; print}' file

На основе предложения @ ghostdog74. Мой должен вести себя лучше, когда вы фильтруете строки, а именно:

awk '/^exim4-config/ {$1=""; print }' file
person Wawrzek    schedule 01.06.2011
comment
Коротко и просто. Можно также добавить sed 's/\s\+//g' в конце команды, чтобы обрезать ведущие пробелы - person jumping_monkey; 13.03.2020

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

Это обрезает то, что находится перед данным полем №, N, и печатает всю остальную часть строки, включая поле №N и сохраняя исходный интервал (он не переформатируется). Не имеет значения, появляется ли строка поля где-то еще в строке, что является проблемой с ответом daisaa.

Определите функцию:

fromField () { 
awk -v m="\x0a" -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' является разделителем записей, поэтому у вас нет символа новой строки внутри строк. Если вы хотите использовать его с другими разделителями записей, используйте:

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

Например. Хорошо работает почти со всеми файлами, если в них не используется шестнадцатеричный номер символа. 1 внутри линий.

person Robert Vila    schedule 16.04.2014

awk '{a=match($0, $3); print substr($0,a)}'

Сначала вы найдете позицию начала третьего столбца. С помощью substr вы напечатаете всю строку ($ 0), начиная с позиции (в данном случае a) до конца строки.

person Mitchjol    schedule 10.11.2017

Следующая команда awk печатает последние N полей каждой строки, а в конце строки печатает символ новой строки:

awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'

Найдите ниже пример, в котором перечисляется содержимое каталога / usr / bin, затем содержатся последние 3 строки, а затем печатаются последние 4 столбца каждой строки с помощью awk:

$ ls -ltr /usr/bin/ | tail -3
-rwxr-xr-x 1 root root       14736 Jan 14  2014 bcomps
-rwxr-xr-x 1 root root       10480 Jan 14  2014 acyclic
-rwxr-xr-x 1 root root    35868448 May 22  2014 skype

$ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Jan 14 2014 bcomps 
Jan 14 2014 acyclic 
May 22 2014 skype
person funk    schedule 08.12.2014

Что ж, вы можете легко добиться того же эффекта, используя регулярное выражение. Если предположить, что разделитель - это пробел, это будет выглядеть так:

awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'
person Eddie Sullivan    schedule 21.10.2009
comment
Я бы избегал регулярных выражений. Это, наверное, медленнее и проще случайно испортить. - person Cascabel; 21.10.2009
comment
Он укорачивает его так: awk '{ sub(/([^ ]+ +){2}/, ""); print }', который убирает узор в два раза. - person erik; 11.01.2014

Решение Perl:

perl -lane 'splice @F,0,2; print join " ",@F' file

Используются следующие параметры командной строки:

  • -n цикл вокруг каждой строки входного файла, не печатать автоматически каждую строку

  • -l удаляет символы новой строки перед обработкой и добавляет их после

  • -a режим autosplit - разбивать входные строки на массив @F. По умолчанию разделение на пробелы

  • -e выполнить код Perl

splice @F,0,2 чисто удаляет столбцы 0 и 1 из массива @F

join " ",@F объединяет элементы массива @F, используя пробел между каждым элементом

Если ваш входной файл разделен запятыми, а не пробелами, используйте -F, -lane


Решение Python:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file

person Chris Koknat    schedule 16.09.2015

Немного поздно, но ничего из вышеперечисленного, похоже, не сработало. Попробуйте это, используя printf, вставляя пробелы между ними. Я решил не использовать новую строку в конце.

awk '{for(i=3;i<=NF;++i) printf("%s ",  $i) }'
person Ross    schedule 24.01.2013

awk '{for (i=4; i<=NF; i++)printf("%c", $i); printf("\n");}'

печатает записи, начиная с 4-го поля до последнего поля в том же порядке, в котором они были в исходном файле

person Massimo    schedule 14.11.2014
comment
извините, это был не совсем правильный ответ. он слишком конкретен, но я не знаю, как его удалить - person Massimo; 14.11.2014

В Bash вы можете использовать следующий синтаксис с позиционными параметрами:

while read -a cols; do echo ${cols[@]:2}; done < file.txt

Подробнее: Обработка позиционных параметров на Bash Hackers Wiki

person kenorb    schedule 10.04.2016

Если речь идет только об игнорировании первых двух полей и если вам не нужен пробел при маскировке этих полей (как это делают некоторые из ответов выше):

awk '{gsub($1" "$2" ",""); print;}' file
person champost    schedule 21.02.2016

awk '{$1=$2=""}1' FILENAME | sed 's/\s\+//g'

Первые два столбца очищаются, sed удаляет начальные пробелы.

person sjas    schedule 23.11.2016

В AWK столбцы называются полями, поэтому NF - это ключ

все строки:

awk -F '<column separator>' '{print $(NF-2)}' <filename>

только первая строка:

awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>
person angelo.mastro    schedule 01.12.2017

person    schedule
comment
awk '{for (i = 3; i ‹= NF; ++ i) print $ i}' будет более компактным. :) - person user172818; 21.10.2009
comment
Спасибо, lh3. Я просто копировал и вставлял руководство по gawk. :) - person Jonathan Feinberg; 21.10.2009
comment
Я думаю, что можно сделать что-то подобное awk 'NF >= 3' - person SergioAraujo; 10.05.2013
comment
это не удается с несколькими строками, каждый столбец обрабатывается как новая строка при печати iwth print - person meso_2600; 01.04.2015
comment
@ user2571881, который печатает для меня только результаты с полями, равными или превышающими 3, а не только остаток ПОСЛЕ этих 3 - person Madivad; 18.05.2016
comment
Разделенный вывод отображается с помощью newline separator. У меня не работает. - person gies0r; 09.04.2017
comment
Чтобы решить проблему с разделенным выводом, я предлагаю следующее решение: awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}' (printf не будет печатать символ новой строки, а print "" добавит новую строку после того, как другие поля будут напечатаны) - person lauhub; 19.09.2017
comment
Или: echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}', что дает: 3 4 5 6 7 8 9 10. - person x-yuri; 05.12.2017
comment
Он добавляет каждый столбец в отдельную строку. См. Ответ: stackoverflow.com/a/49130247/3154883 - person Brother; 14.08.2018