awkを使用して特定の番号の後にすべての列を印刷するにはどうすればよいですか?


回答:


83
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

3
いくつかのわずかな改良:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman 2011

@glennに感謝します、それは確かにもう少し一般的です。とにかく-私は間違いなくそれを使用するcutperl、これに使用する方が良いと思います。あなたが本当にそれをに持つことを主張する場合にのみこれを使用してくださいawk
アマダン2011

1
@SiegeX:NULバイトを追加せず、各空のフィールドの間にFSを残します。
デニスウィリアムソン

1
エレガンスについては@Aschererの回答をご覧ください。

3
@veryhungrymike:エレガンスは素晴らしいですが、私はむしろ正しいと思います。:p
アマダン2013年

68

さまざまなフィールドを実行したい場合、awkこれを実行する簡単な方法は実際にはありません。cut代わりに私はお勧めします:

cut -d' ' -f 9- ./infile

編集

デフォルトがタブであるため、スペースフィールド区切り文字が追加されました。これを指摘してくれたGlennに感謝します


15
カットについての1つのことは、awkが「空白」を使用する特定の区切り文字(デフォルトではタブ)を使用することです。カットでは、2つの連続するタブが空のフィールドを区切ります。
glenn jackman 2011

1
@glennjackmanが指摘したように、awkの区切り文字は「空白」です(任意の量も)。したがって、カット区切り文字を単一のスペースに設定すると、動作も一致しません。残念ながら、ループは実行できる最善の方法であるため、見た目は同じです。
poncha 2013

これは正しく動作しません。コマンドを試してくださいfind . | xargs ls -l | cut -d' ' -f 9-。何らかの理由で、ダブルスペースもカウントされます。例:lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_b結果は./file_a 00:06 ./file_b
Marco Pashkov 2015

@MarcoPashkovについて詳しく説明してください。特に、パイプラインでまったく同じコードを使用していることを考えると、これは正しく機能しません。ちなみに、lsの出力を解析しようとしないでください
SiegeX 2015年

カットはここでは仕事をしません。たとえば、入力が1行の「foobar」(単一スペース)であり、別の行の「foo ___ bar」(つまり、複数のスペースですが、SOはスマートすぎて表示できません)の場合、cutはそれらを異なる方法で処理します。
UKMonkey

54
awk '{print substr($0, index($0,$9))}'

編集:注:9番目より前のフィールドに9番目と同じ値が含まれている場合、これは機能しません。


10
@veryhungrymike:...そして、9番目より前のフィールドに9番目と同じ値が含まれている場合は機能しません。
アマダン2013年

6
おそらく、「ファイルにその問題がないことを願っています」という古典的な文が原因です。それは、全ません無なし状態にS / Wエンジニアリングに:「我々は、ユーザーがそれらを試していないと、十分な知的ことを願っています」ので、我々は、エラーチェックなど、負の値を入力するなど、時間を無駄にするつもりはありませんツールのクラッシュ '"。ハハハ!いつもこれを聞くのが大好きです!馬鹿のように(ユーモアのセンスのようなI)まあ、やるが存在し、それは彼のものを作るために、開発者の義務だばかプルーフ!「人の善を願う」代わりに。これは、s / wエンジニアではなく、哲学者に期待される態度です... LOL
Syntaxerror 2014

3
エラーをチェックしないと言っているわけではありませんが、問題が発生しないことがわかっている場合は、前述のように、この解決策で問題ありません。しかし、不必要な反対票@syntaxerrorをありがとう。(現在)19の賛成票が表示されるように、このソリューションは一部のユーザーには機能しますが、機能しない場合は、ソリューションに使用しないでください。OPの問題を解決する方法はたくさんあります。
Ascherer 2014

1
日常業務のコマンドラインでawkを使用している場合、これは間違いなく必要なソリューションです。明らかではありませんか?エラーチェックなどは、入力しているので実際には問題ではなく、Enterキーを押す前にこれらの種類のものをキャッチできます(個人的には、awkを他の目的に使用するべきではないと思います。そのため、 'perl、python、tcl、およびその他の約100以上の、より優れた、より高速な、煩わしくないスクリプト言語があります!)'コース多分Imは私の仲間のソフトウェア開発者にあまりにも多くの信用を与えており、彼らが入力したものでもエラーチェックが本当に必要ですオンザフライ(??)
osirisgothra 2015

1
それが答え以下にその権利として、それを必要に応じて、私はそれが@attiに添加していないこと
Ascherer

11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

可変幅の空白を処理する代わりに、すべての空白を単一のスペースとして置き換えます。次にcut、関心のあるフィールドでsimpleを使用します。

それはawkを使用しないので、密接な関係はありませんが、他の回答/コメントを考えると適切であるように思われました。


1
あなたの答えをもっと徹底的にしてください、さもなければ質問へのコメントとしてこれを投稿してください。
Alper Turan

これはps faux | 使用に理想的です。ツールXYZが最も適切ではないことを認めることを恐れないでください。
kevinf 2016

10

通常、perlはawk / sed / grepetを置き換えます。al。、そしてはるかにポータブルです(そしてより良いペンナイフであるだけでなく)。

perl -lane 'print "@F[8..$#F]"'

もちろん、Timtowtdiが適用されます。


コマンドラインオプション-lを追加\nするか、printステートメントに追加する必要があります。
glenn jackman 2011

@glenn jackman:おそらく。別のメッセージの一部である場合、または変数に割り当てられている場合などは必要ありません。「より良い」という限り、perlは確かに小さい方が見栄えがします。確かに大規模で非常に乱雑に見えることができます。
bobbogo 2011

誤解しないでください、私はPerlが好きです。私はそれが何であるかについてawkが大好きです。
glenn jackman 2011

私の埋め込みデバイスにはPerlが付属していませんが、awkがあります。
セペロ2014

質問がperl、ruby、java、python、bashではなくawkでこれを行う方法を尋ねたため、反対票を投じました。
トムハリソン

3
awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

これにより、指定されたフィールドnr。、Nの前にあるものが切り取られ、フィールドnr.Nを含み、元の間隔を維持しながら、行の残りすべてが出力されます(再フォーマットされません)。フィールドの文字列が行の別の場所にも表示されているかどうかは問題ではありません。これは、Aschererの回答の問題です。

関数を定義します。

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

そして、次のように使用します。

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

出力は、末尾のスペースを含むすべてを維持します。N= 0の場合は行全体をそのまま返し、n> NFの場合は空の文字列を返します。


これは良い考えです。$ 0が崩壊するため、典型的なgawkを使用している現在のMacでは完全には機能しません。修正は、最初のステップとして次のように変数を$ 0に設定することです。 '{s = $ 0; ... print substr(s、index(s、m)+1}
joelparkerhenderson 2015年

1

ls -l出力の例を次に示します。

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

投稿を印刷する私の解決策$9awk '{print substr($0, 61, 50)}'



0

最初の3つのフィールドを表示し、残りのフィールドを印刷するには、次を使用できます。

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

ここで、$ 1 $ 2 $ 3は最初の3つのフィールドです。


0
function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

0

awkの代わりにcutを使用し、-c charactercutコマンドを使用してどの列から開始するかを判断する際の問題を克服します。

ここで私が言っているのは、出力の最初の49文字を除くすべてを教えてください。

 ls -l /some/path/*/* | cut -c 50-

/*/*/lsコマンドの最後には、あまりにもサブディレクトリにあるもののショーを私に言っています。

また、特定の範囲の文字alaを(カットマンページから)引き出すこともできます。たとえば、現在ログインしているユーザーの名前とログイン時間を表示します。

       who | cut -c 1-16,26-38
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.