Варіанти 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-
?