Большинство решений с awk оставляют место. Варианты здесь позволяют избежать этой проблемы.
Опция 1
Простое решение для резки (работает только с одиночными разделителями):
command | cut -d' ' -f3-
Вариант 2
Принудительный пересчет awk иногда удаляет добавленный начальный пробел (OFS), оставленный путем удаления первых полей (работает с некоторыми версиями awk):
command | awk '{ $1=$2="";$0=$0;} NF=NF'
Вариант 3
Печать каждого поля, отформатированного с помощью printf
, даст больше контроля:
$ in=' 1 2 3 4 5 6 7 8 '
$ echo "$in"|awk -v n=2 '{ for(i=n+1;i<=NF;i++) printf("%s%s",$i,i==NF?RS:OFS);}'
3 4 5 6 7 8
Однако все предыдущие ответы меняют все повторяющиеся FS между полями на OFS. Давайте создадим пару вариантов, которые этого не делают.
Вариант 4 (рекомендуется)
Цикл с подпрограммой для удаления полей и разделителей спереди.
И используя значение FS вместо пробела (который можно изменить).
Является более переносимым и не вызывает смену FS на OFS:
ПРИМЕЧАНИЕ . ^[FS]*
Принимает ввод с начальными пробелами.
$ in=' 1 2 3 4 5 6 7 8 '
$ echo "$in" | awk '{ n=2; a="^["FS"]*[^"FS"]+["FS"]+";
for(i=1;i<=n;i++) sub( a , "" , $0 ) } 1 '
3 4 5 6 7 8
Вариант 5
Вполне возможно построить решение, которое не добавляет лишние (начальные или конечные) пробелы и сохраняет существующие пробелы, используя функцию gensub
из GNU awk, как это:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
{ print(gensub(a""b""c,"",1)); }'
3 4 5 6 7 8
Он также может быть использован для замены группы полей по количеству n
:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
{
d=gensub(a""b""c,"",1);
e=gensub("^(.*)"d,"\\1",1,$0);
print("|"d"|","!"e"!");
}'
|3 4 5 6 7 8 | ! 1 2 !
Конечно, в таком случае OFS используется для разделения обеих частей линии, и завершающий пробел полей по-прежнему печатается.
ПРИМЕЧАНИЕ: [FS]*
используется для разрешения начальных пробелов в строке ввода.
grep | awk
это антипаттерн - вы хотитеawk '/!/ { print $2 }'