オプション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
フィールドと区切り文字を削除するsubを含むループは移植性が高く、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-
か?