Tùy chọn 1 đến 3 có vấn đề với nhiều khoảng trắng (nhưng rất đơn giản). Đó là lý do để phát triển các tùy chọn 4 và 5, xử lý nhiều khoảng trắng mà không có vấn đề gì. Tất nhiên, nếu tùy chọn 4 hoặc 5 được sử dụng với n=0
cả hai sẽ bảo toàn bất kỳ khoảng trắng đầu nào nhưn=0
đồng nghĩa với việc không chia tách.
lựa chọn 1
Một giải pháp cắt đơn giản (hoạt động với các dấu phân cách đơn):
$ echo '1 2 3 4 5 6 7 8' | cut -d' ' -f4-
4 5 6 7 8
Lựa chọn 2
Việc buộc một re-calc awk đôi khi giải quyết được vấn đề (hoạt động với một số phiên bản awk) của các khoảng trống ở đầu được thêm vào:
$ echo '1 2 3 4 5 6 7 8' | awk '{ $1=$2=$3="";$0=$0;} NF=NF'
4 5 6 7 8
Lựa chọn 3
Việc in từng trường được định dạng printf
sẽ giúp kiểm soát nhiều hơn:
$ 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
Tuy nhiên, tất cả các câu trả lời trước đó đều thay đổi tất cả FS giữa các trường thành OFS. Hãy xây dựng một vài giải pháp cho điều đó.
Lựa chọn 4
Một vòng lặp với con để loại bỏ các trường và dấu phân cách là linh hoạt hơn và không kích hoạt thay đổi FS thành 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
LƯU Ý: "^ [" FS "] *" là chấp nhận đầu vào có dấu cách ở đầu.
Lựa chọn 5
Hoàn toàn có thể xây dựng một giải pháp không thêm khoảng trắng ở đầu hoặc cuối và bảo toàn khoảng trắng hiện có bằng cách sử dụng hàm gensub
từ GNU awk, như sau:
$ 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ó cũng có thể được sử dụng để hoán đổi danh sách trường đã cho một số lượng 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 !
Tất nhiên, trong trường hợp này, OFS được sử dụng để tách cả hai phần của dòng và khoảng trắng ở cuối của các trường vẫn được in.
Note1: ["FS"]*
được sử dụng để cho phép khoảng trắng ở đầu dòng nhập.
cut -f3-
?