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


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.