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