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


121

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


Ответы:


108

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


9
Обратите внимание, что это работает только в том случае, если разделитель во всех столбцах точно такой же ... Например, вы не можете использовать вырезку с разделителем, например \ d +. (Это я знаю.)
— Зак Вили,

72
Когда вопрос называется awk, неуместно принимать ответ, отличный от awk. Что делать, если людям это нужно для сценариев awk? Этот ответ должен был быть просто комментарием.
— syaz

24
@SyaZ: Обычно я бы согласился, но, учитывая количество «беспричинной awk» на этой доске, я подумал, что нужно показать альтернативный способ выполнения задачи. Разве вы не были бы благодарны, если бы кто-нибудь показал вам более простой и быстрый способ выполнить ту же задачу? Может быть, автор сообщения подумал, что awk - единственный способ сделать это из-за большого количества «не неправильных, но, безусловно, улучшаемых» ответов на другие вопросы?
— Marcin

12
Вот для чего этот комментарий. Примите лучший ответ awk и предоставьте лучшие не-awk предложения по комментариям. Если люди начнут публиковать ответы, в которых нет точных ответов на вопросы, это будет раздражать при поиске (в моем случае).
— syaz

12
Не только разделитель должен быть одинаковым для всех столбцов, но должен быть ТОЧНО ОДИН символ разделителя между столбцами. Поэтому, если вы имеете дело с программами, вывод которых выравнивается с помощью разделителей, лучше использовать awk.
— sknaumov

112
awk '{for(i=3;i<=NF;++i)print $i}' 

3
awk '{for (i = 3; i <= NF; ++ i) print $ i}' будет более компактным. :)
— user172818

1
Спасибо, lh3. Я просто копировал и вставлял руководство по gawk. :)
— Джонатан Фейнберг

23
это не удается с несколькими строками, каждый столбец отображается как новая строка при печати iwth print
— meso_2600 01

13
Чтобы решить проблему с разделенным выводом, я предлагаю следующее решение: awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}'( printfне будет печатать символ новой строки, а print ""добавит новую
— строку

1
Или: echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}', что дает: 3 4 5 6 7 8 9 10.
— x-

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

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


23
Я немного опоздал с этим, но это не сработает для записей, в которых первое или второе поле равно третьему (например, 3 2 3 4 5)
— aleph_null

также возможна печать внутреннего диапазона: `` # от 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 ''
— splaisan

34

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

awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile

1
Имейте в виду, что это работает только для Gnu awk, уменьшение NFв POSIX запрещено.
— kvantour

1
@kvantour: Работает в gawk, mawk, MacOS awk (nawk?). POSIX, похоже, ничего не говорит о NFвозможности уменьшения.
— Приостановлено до дальнейшего уведомления.

Это один из забавных темных уголков awk .
— квантур

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

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


Отследите эту команду с помощью `| sed s / ^ \ * // | column -t`, чтобы удалить ведущие пробелы и выровнять оставшиеся столбцы
— MSpreij

Что значит последнее 1? по какому ключевому слову мне следует искать awk?
— Итачи


1
@Nathan, вы решите эту проблему как{$1=$2=$3="";$0=$0;$1=$1}1
— квантур

11

Если вы хотите напечатать столбцы после 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

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


Быстро и гладко. Спасибо;)
— 9nz9

Это отлично, за исключением того, что у меня проблема с исключением $ NF. Когда я устанавливаю условие (<= NF), я получаю последнее поле, но первый символ первого поля обрезается. Я что-то неправильно понимаю с точки зрения функциональности?
— Кен Ингрэм

Похоже, моя проблема в том, что ^ M застрял в конце последнего столбца. Не вижу, как его удалить.
— Кен Ингрэм

8

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

awk '{$ 1 = $ 2 = $ 3 = ""; распечатать файл

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

awk '/ ^ exim4-config / {$ 1 = ""; распечатать файл

Коротко и просто. Можно также добавить sed 's/\s\+//g'в конец команды
— вертикальную черту,

8
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 внутри линий.


4

Следующая команда 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

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

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


3

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

awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'

1
Я бы избегал регулярных выражений. Это, наверное, медленнее и проще случайно испортить.
— Cascabel

1
Он укорачивает его так: awk '{ sub(/([^ ]+ +){2}/, ""); print }'при этом узор удаляется в два раза.
— erik


2

Решение 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


1

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

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

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

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


извините, это был не совсем правильный ответ. он слишком конкретен, но я не знаю, как его удалить
— Массимо


0

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

awk '{gsub($1" "$2" ",""); print;}' file

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

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


-2

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

все строки:

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

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

awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.