3番目の列を最後の列に印刷する方法は?


121

DbgViewログファイルから最初の2つの列(対象ではない)を削除しようとしています。3カラム目以降から行末まで印刷する例が見つからないようです。各行には可変数の列があることに注意してください。


回答:


108

...またはより簡単な解決策:cut -f 3- INPUTFILE 正しい区切り文字(-d)を追加するだけで、同じ効果が得られます。


9
これは、区切り文字がすべての列でまったく同じ場合にのみ機能することに注意してください。たとえば、\ d +のような区切り文字を指定してcutを使用することはできません。(私が知っていること)
ザックウィリー2010年

72
質問のタイトルがawkの場合、awk以外の回答を受け入れることは不適切です。人々がawkスクリプトにそれを必要としたらどうでしょうか?この回答はコメントにすぎません。
syaz

24
@SyaZ:通常、私は同意しますが、このボードに「不当なawk」がいくつもあるので、タスクを実行する別の方法を示す必要があると思いました。同じタスクを実行するためのより簡単で迅速な方法が誰かに示されていたら、感謝しませんか?たぶんポスターは、他の質問に対する回答が「正しくないが、確実に改善できる」数が多いため、awkがこれを行う唯一の方法だと思ったのでしょうか。
Marcin、2011年

12
それがコメントの目的です。最高のawk回答を受け入れ、コメントに対してより適切な非awk提案を提供します。人々が質問に正確に答えない回答を投稿し始めると、(私の場合)検索するのは面倒になります。
syaz

12
区切り文字はすべての列で同じである必要があるだけでなく、列間で正確に1つの区切り文字が必要です。したがって、出力を区切り文字で揃えるプログラムを扱っている場合は、awkを使用することをお勧めします。
sknaumov 2012

112
awk '{for(i=3;i<=NF;++i)print $i}' 

3
awk '{for(i = 3; i <= NF; ++ i)print $ i}'はよりコンパクトになります。:)
user172818 2009年

1
ありがとう、lh3。私はgawkマニュアルをコピーして貼り付けていました。:)
ジョナサンファインバーグ、

23
これは複数行で失敗し、各列は印刷されたときに新しい行として扱われます
meso_2600

13
分割さ出力の問題に対処するために、私はこのソリューションを提案している:awk '{for(i=3;i<=NF;++i)printf $i""FS ; print ""}'printf改行文字の中には印刷されませんprint ""、他のフィールドが印刷された後に改行が追加されます)
lauhub

1
または:echo $(seq 1 10) | awk '{for (i=3; i<=NF; i++) printf $i FS}'、これにより:3 4 5 6 7 8 9 10
x-yuri 2017

106
awk '{ print substr($0, index($0,$3)) }'

解決策はここにあります:http :
//www.linuxquestions.org/questions/linux-newbie-8/awk-print-field-to-end-and-character-count-179078/


23
ちょっと遅れましたが、最初または2番目のフィールドが3番目のフィールドと等しいレコード(たとえば、3 2 3 4 5)には
機能しません

内部範囲の出力も可能です: `` `#から$ 3(含まれている)から$ 6(除外されている); エコー "1,2,3,4,5,6,7,8,9" | awk 'BEGIN {FS = "、"; OFS = "、"} {print substr($ 0、index($ 0、$ 3)、length($ 0)-index($ 0、$ 6)-1)}'; #3、4、5を与える `''
splaisan

34

Jonathan Feinbergの回答は、各フィールドを別々の行に出力します。を使用printfして同じ行に出力用のレコードを再構築できますが、フィールドを左にジャンプして移動することもできます。

awk '{for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; print}' logfile

1
これはGnu awkでのみ機能することに注意してくださいNF。デクリメントはPOSIXでは許可されていません。
kvantour

1
@kvantour:gawk、mawk、MacOS awk(nawk?)で動作します。POSIX NFは、デクリメントできるかどうかについては黙っています。
追って通知があるまで一時停止。

これは、awkのこれらの面白い暗いコーナーの 1つです。
kvantour

19
awk '{$1=$2=$3=""}1' file

注:この方法では、出力を確認するだけであれば、1,2,3フィールドに「空白」が残りますが、問題はありません。


`|でそのコマンドを追跡します sed s / ^ \ * // | 先頭のスペースを削除して残りの列を揃えるcolumn -t`
MSpreij

最後は1どういう意味ですか?どのキーワードで検索すればよいawkですか?
イタチ

@Itachiはcatonmat.net/blog/awk-one-liners-explained-part-oneの例1を参照
kvantour

1
@Nathanあなたはこの問題を次のように解決します{$1=$2=$3="";$0=$0;$1=$1}1
kvantour

11

同じ行の3番目以降の列を印刷する場合は、次のように使用できます。

awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}'

例えば:

Mar 09:39 20180301_123131.jpg
Mar 13:28 20180301_124304.jpg
Mar 13:35 20180301_124358.jpg
Feb 09:45 Cisco_WebEx_Add-On.dmg
Feb 12:49 Docker.dmg
Feb 09:04 Grammarly.dmg
Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf

印刷されます:

20180301_123131.jpg
20180301_124304.jpg
20180301_124358.jpg
Cisco_WebEx_Add-On.dmg
Docker.dmg
Grammarly.dmg
Payslip 10459 %2828-02-2018%29.pdf

ご覧のとおり、スペースがあっても給与明細は正しい行に表示されます。


素早く滑らか。ありがとう;)
9nz9

$ NFが除外されるという問題があることを除いて、これは優れています。条件(<= NF)を設定すると、最後のフィールドが表示されますが、最初のフィールドの最初の文字が切り落とされます。機能の点で誤解していますか?
ケンイングラム

私の問題は、^ Mが最後の列の最後に止まっていることです。それを削除する方法がわかりません。
ケンイングラム

8

次の行はどうですか:

awk '{$ 1 = $ 2 = $ 3 = ""; print} 'ファイル

@ ghostdog74の提案に基づいています。次のように、ラインをフィルタリングすると、鉱山の動作が改善されます。

awk '/ ^ exim4-config / {$ 1 = ""; }ファイルを印刷

短くてシンプル。sed 's/\s\+//g'コマンドの最後にパイプして追加し、先頭のスペースを
削除

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

これは、指定されたフィールドnr。、Nの前にあるものを切り取り、フィールドnr.Nを含めて、行の残りのすべてを印刷し、元の間隔を維持します(再フォーマットしません)。フィールドの文字列が行の他の場所にも現れる場合は問題になりません。これは、daisaaの回答の問題です。

関数を定義します。

fromField () { 
awk -v m="\x0a" -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'がレコードセパレータであるファイルでうまく機能するため、行内に改行文字がありません。他のレコードセパレータと一緒に使用したい場合は、次を使用します。

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

例えば。16進文字nrを使用しない限り、ほとんどすべてのファイルで問題なく動作します。行の内側に1つ。


4

次のawkコマンドは、各行の最後のNフィールドを出力し、行の終わりに改行文字を出力します。

awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'

/ usr / binディレクトリの内容を一覧表示し、最後の3行を保持し、awkを使用して各行の最後の4列を出力する例を以下に示します。

$ ls -ltr /usr/bin/ | tail -3
-rwxr-xr-x 1 root root       14736 Jan 14  2014 bcomps
-rwxr-xr-x 1 root root       10480 Jan 14  2014 acyclic
-rwxr-xr-x 1 root root    35868448 May 22  2014 skype

$ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }'
Jan 14 2014 bcomps 
Jan 14 2014 acyclic 
May 22 2014 skype

4
awk '{a=match($0, $3); print substr($0,a)}'

まず、3列目の開始位置を見つけます。substrを使用すると、行全体($ 0)をその位置(この場合はa)から行末まで印刷します。


3

まあ、正規表現を使用して同じ効果を簡単に実現できます。セパレータがスペースであるとすると、次のようになります。

awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }'

1
正規表現は避けます。誤って失敗するのはおそらく遅く、簡単です。
Cascabel、

1
これは次のように短縮されます。awk '{ sub(/([^ ]+ +){2}/, ""); print }'これにより、パターンが2倍になります。
erik 2014年


2

Perlソリューション:

perl -lane 'splice @F,0,2; print join " ",@F' file

次のコマンドラインオプションが使用されます。

  • -n 入力ファイルのすべての行をループし、自動的にすべての行を印刷しない

  • -l 処理前に改行を削除し、後で追加します

  • -a自動分割モード-入力行を@F配列に分割します。デフォルトでは空白での分割

  • -e Perlコードを実行する

splice @F,0,2 @F配列から列0と1をきれいに削除します

join " ",@F 各要素の間にスペースを使用して、@ F配列の要素を結合します

入力ファイルがスペース区切りではなくカンマ区切りの場合は、 -F, -lane


Pythonソリューション:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file


1

ここでは少し遅れましたが、上記のどれも機能しないようです。printfを使用してこれを試し、それぞれの間にスペースを挿入します。最後に改行を入れないことにしました。

awk '{for(i=3;i<=NF;++i) printf("%s ",  $i) }'

1
awk '{for (i=4; i<=NF; i++)printf("%c", $i); printf("\n");}'

4番目のフィールドから最後のフィールドまでのレコードを、元のファイルと同じ順序で印刷します


申し訳ありませんが、これはまったく正しい答えではありませんでした。具体的すぎますが、削除方法がわかりません
Massimo


0

最初の2つのフィールドを無視することだけが目的で、これらのフィールドをマスキングするときにスペースが不要な場合(上記の回答の一部と同様):

awk '{gsub($1" "$2" ",""); print;}' file

0
awk '{$1=$2=""}1' FILENAME | sed 's/\s\+//g'

最初の2列がクリアされ、sed先行スペースが削除されます。


-2

AWKでは列はフィールドと呼ばれるため、NFが重要です

すべての行:

awk -F '<column separator>' '{print $(NF-2)}' <filename>

最初の行のみ:

awk -F '<column separator>' 'NR<=1{print $(NF-2)}' <filename>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.