• ベストアンサー

AWKで1項目以外を簡単に出力したい

awkのprint出力で$1$2$3$4$5$6と書くのではなく、$1から$6までを簡潔に指定できる方法はありませんか? (たとえば$1-$6のような) すべて出力したい場合は$0でいいのですが、1項目だけ除外してあとはすべて出力したい時に項目が多い大変ですから。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

最後のフィールドだけ消せばいいのなら、組み込み変数NFをデクリメント してやればいいです。$7=""だと中身が空のフィールドになるだけなので 余計なセパレータが出力されるように見えているのです。 ひょっとしたらNFをデクリメントしたあとで$0の再構築を 強制的にさせる必要があるかもしれません($0=$0 とか $1=$1で やってくれるはず)。

ritomo
質問者

お礼

ありがとうございました。 awk 'BEGIN {FS="|"} {OFS="|"; $7=""; NF=6; print $0}' ./aaaaでうまくいきました。 $0の再構築は必要ないようです。 入力:111|222|333|444|555|666|777 出力:111|222|333|444|555|666 awk 'BEGIN {FS="|"} {OFS="|"; $7=""; NF=6; $0=$0; print $0}'./aaaa の場合は「awk: $0 の設定ができません」というエラーになるようです。 ちなみに途中の項目を抜くのはどんな方法を使えばよろしいのでしょうか? (たとえば、$3だけを抜かして表示) よろしかったら教えていただけないでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

詳しくは参考URLの先を読んでいただくとして、 あるフィールドを空文字列にすることはできますが、それは内容が 空のフィールドを作るだけで削除ではありません。 ですので、ご希望のような途中のフィールドを簡単に削除してしまう ようなことは残念ながらできません。 仮にOFSがフィールドの内容として絶対に出てこないならば、削除したい フィールドに空文字列を代入した後で、連続したOFSをひとつのOFSにする gsubを実行するくらいが代案でしょうか(OFSが正規表現のメタ文字である ときには要注意)。

参考URL:
http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_6.html#SEC37
ritomo
質問者

お礼

ご回答ありがとうございました。返事が遅れてもうしわけありません。 フィールドの簡単な削除はできない件、わかりました。 1行をfor文などで繰り返しながら処理し、N項番目だけprintしないなどの方法を考えてみます。 ご提示のURLは参考になりました。ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.1

$1-$6というような書き方はできませんが、$1から$7まであって、$1から$6を表示したいなら、 $7="";print $0 と言う書き方があります。$7の値をこの後に使いたいのであれば、 tmp=$7;$7="";print $0;$7=tmp と一度変数に保存しておいて戻すという方法もあります。

ritomo
質問者

お礼

早速の回答ありがとうございます。 項番個所を""で上書きするイメージですね。便利なものを教わりました。ありがとうございます。

ritomo
質問者

補足

先ほどの回答ありがとうございます。 気になる点があります。このままですとOFSを付けないと"|"のセパレータが消えてしまう点、 最後のセパレータが残ってしまいます。 >> more aaaa 111|222|333|444|555|666|777 >> x.sh 111|222|333|444|555|666| >> more x.sh #!/bin/csh awk 'BEGIN {FS="|"} {OFS="|";$7="";print $0}' ./aaaa セパレータ+項目を1セットで無くす方法があればいいのですが。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • awkのsplitについて

    awkにつて質問いたします。 awkで項目を特定する時$1等指定しますが、最大で$199までしか対応していない事が分かりました。 そこでawk内部でsplitを使う事にしました。(この場合、200項目目以上可能) 項目の特定、変更は分かりましたが、レコード単位での出力("print 配列"等)の方法分かりません。 簡単に言いますと、 1.あるレコードのある項目を変更したい 2.変更後、レコード単位でファイルに出力したい ※項目は区切り文字で仕切られている ※項目は200以上ある です。 for文で回すのは最終手段にしたいと考えています。 ※この方法でしたら、実現しています。 ご存知の方、ご教授願えますか? 宜しくお願いいたします。

  • Bシェルのawkコマンドについて

    Bシェルのawkコマンドについてですが、例えばプロンプトから % ls -l hoge.txt | awk '{print $5}' と入力すると、hoge.txtのファイルサイズが出力されますが、同様のことをBシェルの中で行おうと思っています。 下記のように、配列arrayにはスペース区切りで3つのデータが入っており、N番目のデータを取得したいという場合に、Nに変数を使用して取得する方法がわかりません。 #!/bin/sh array="AA BB CC" num=3 # CCを取得したい echo $array | awk '{print $num}' 上記で実行すると、"AA BB CC"のようにすべて出力されてしまいます。awkで出力する箇所を${数値}で指定すればうまくいくのですが、ランダムで決めた数値(1~3)をnumに入れて取得したい場合、このようなことは可能でしょうか。 もし不可能な場合でも、awk以外に何かコマンドがあればご教授願います。なお、作成するのはBシェルになります。

  • awkのセパレータ指定について

    awkのセパレータ指定について教えてください。 以下のようなファイルがありそれを'||'区切りで出力したいです。 下記のような指定をしてみたのですが、 うまくいきませんでした。 cat text | awk -F '||' '{print $1}' [test.txt] aaa||bbb||ccc [期待する結果] print $1 → aaa print $2 → bbb print $3 → ccc どなたか教えてください。 よろしくお願いします。

  • awkコマンドに引数を渡す方法

    awkコマンドに対して引数を渡す方法が知りたいです。 例えば以下のようなリストファイルがあったとします。 --------------------------------------- % cat test.lst 454 100 37536 200 32432 300 34q2 400 --------------------------------------- そこで以下のシェルを実行すると --------------------------------------- #!/bin/sh for VAL in 100 200 300 do CNT=`cat test.lst | awk '$2 == $VAL {print $1}'` echo "$VAL : $CNT" done --------------------------------------- awkコマンド内の$VALが引数ではなく文字列として認識されてしまうため、 出力結果が 100 : 200 : 300 : となってしまいます。 100 : 454 200 : 37536 300 : 32432 という結果を出力したい場合(awk内の引数を有効にする場合)どうすればよいでしょうか? awkを使用しない方法もあるかと思いますが、今回はawkを使った方法を知りたいです。 宜しくお願い致します。

  • awk '{print $1}' file をもっと簡単に書きたい

    awkで最も頻繁に使うのが、fileのN列目だけを抜き取ってくるという使い方なんですが ↓ awk '{print $N}' file Nとfileという2つの引数しか使わないのでこれを   my_awk N file  といった具合に間単に使える my_awk シェルを作りたいんですが、$のあたりがうまくかけません、どう直せばいいでしょうか?↓ #!/bin/csh awk '{print $$1}' $2

  • awkで最後の列だけ除外する方法

    「awkのみ」で最後の列だけを区切り文字も含めて除外するのに、スマートな方法は無いでしょうか? x1,x2,x3,…,x98,x99,x100 を x1,x2,x3,…,x98,x99 とする方法です。 $ awk {$100="";print $0} だと最後のカンマが残りますし、かといってprint $1, $2,…$98, $99 はダサいのでやめたいのですが・・・

  • awkで複数ファイルのある列を抽出し出力したい

    awkプログラミングの初心者です。 今、複数ファイル(1000ファイル)から、それぞれある列(すべて同じ列番号)のデータを抜き出して、1つのファイルに出力したいと考えています。 具体的には、1列目に共通項、2列目以降に1000ファイル分の抽出された列を、合計1001列となるような1つのファイルとして出力したいと考えております。 awkを使って出力するには、どのようなスクリプトを作ればよいか教えていただけませんでしょうか。 <イメージ> 元となるファイル(例えば下記のように3ファイル、実際には1000ファイル)があります。 file1.txt: 1  10 2  15 3  17 :  : 1000  25 file2.txt: 1  5 2  40 3  22 :  : 1000  17 file3.txt: 1  9 2  20 3  16 :  : 1000  32 出力後のファイルイメージ: 1  10  5  9 2  15  40  20 3  17  22  16 :  :  :  : 1000  25  17  32 ちなみに、自分で作成したawkスクリプト(下記)では、上記出力後のイメージとは異なり、 縦にデータが結合されてしまいました。 awk `{print $2}` ./file*.txt > Output.txt 出力後のファイル: 10 15 17 : 25 5 40 :

  • awkで各列の最大値を一気に出力

    awkで各列の最大値と最小値を一気に出力する方法を教えてください。特定の列に対する処理はできますが、全ての列について処理する方法が知りたいです。

  • awkでの出力項目の追加方法について

    はじめまして。 急遽UNIXサーバをメンテすることになったUNIX素人です。時間に迫られており勉強する時間も今はとれず、皆様のお知恵をお借りしたく質問させていただきます。 現在、コマンド出力結果などの各行の先頭に、日時分秒を追加してテキストファイル出力するシェルスクリプトの作成をしています。 awk を使用して実現したいと思っていますが、具体的な方法についてアドバイスをいただけたらと思っています。 なお、コマンド出力結果をawkへ引き渡す方法は、スクリプト内で直接渡しても、一旦ファイル出力したものを読み込む形のどちらでもよいと思っています。 例 ・ps の出力結果 PID PPID PGID WINPID TTY UID STIME COMMAND 1072 1 1072 1072 con 1005 10:41:29 /usr/bin/bash 1052 1072 1052 544 con 1005 10:50:14 /usr/bin/ps ・日時分秒 を追加した結果 DATE PID PPID PGID WINPID TTY UID STIME COMMAND 200705111735 1072 1 1072 1072 con 1005 10:41:29 /usr/bin/bash 200705111735 1052 1072 1052 544 con 1005 10:50:14 /usr/bin/ps 大変初歩的な質問で申しわけありませんが、なにどぞご教授お願いします。

  • awkの使い方について教えてください。

    awkとperlなどの初心者です。 使い方が分かっていないのですが、 例えば出力のフィールドセパレータを,に変更するには どうすればいいでしょうか? awk '{OFS=,;print}' fileなどとやってみますが、 うまくいきません。2つ以上のコマンドを実行するときの 文法がわかっていないような気がするのですが。 あとperlでよくみかけるperl -neのnは何でしょうか? man perlとやってみても-wと-eの意味しかのっていなくて なからないのですが。ご教授下さい。