Unix初心者のためのファイルの指定行の標準出力方法

このQ&Aのポイント
  • Unix初心者のために、複数のファイルから指定行のみを取得し、標準出力する方法について教えてください。
  • headやsedなどのコマンドを使用せずに、一行のコマンドで指定行のみを取得する方法があれば教えてください。
  • ファイル名や行数も同時に出力することができれば、さらに効率的な作業ができます。対象行を増やすこともできると嬉しいです。
回答を見る
  • ベストアンサー

多数あるファイル(text base)の*行目だけを引っ張ってきて標準出力させたい。

Unix初心者です。 SunOS > head -1 ./*.txt とすれば、以下のように1行目だけを引っ張ってきて標準出力させる事も可能ですが。 ==> 1234.txt <== hello ==> 1235.txt <== hello SunOS > head -2 ./*.txt とすると、1行目と2行目が標準出力されます。 ==> 1234.txt <== hello bye ==> 1235.txt <== hello bye ですが、以下に例をあげますが、このように " 2行目だけ " を標準出力させたいのです。 ==> 1234.txt <== bye ==> 1235.txt <== bye sed -n '2p' ./*.txt だと、理由は不明ですが一つのファイルしか標準出力されませんでした。 head 、sed でなくともawk grepでも構いません。 その他の自分の知らないコマンドで構いません。 文字検索ではなく、*行目と行数指定です。 できれば、ファイル名も同時に出力させたいのです。 欲を言えば、行数も出力させたいです。 更に、翌を言えば、指定行を増やせたら最高です。 例;)1行目と3行目を標準出力する。 scriptを作りこまずに、|(パイプ)でつなげれば一行のコマンドで処理可能なのでは ないかと想像してますが、いかがでしょうか。 宜しく頼みます。

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

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

> ところで、" nawk " の " n " は、" new " > の頭文字なんですかね。 > (どうでもいいですが) はい。そのとおりです。 ふつうawkというと、このnawkのことを指すことが多いのですが、 SunOSはカタクナなまでに(古い仕様の)awkとnawkを区別して 別個のコマンドにしています。 で、nawkはawkの上位互換のものですので、awkにできて nawkにできないことはありません。 安心してnawkを使ってください。 | 欲をかいて、冷静さをうしなっていたのか、↓これでいいかな。っと思ってます。 | nawk 'FNR==2{print ARGV[++i], $0}' *.txt | grep -n rev | 「 ブサイクだ 」と言われてしまうのでしょか。 パイプの段数が深ければちょっと考えてしまいますが、 このくらいならいいのではないでしょうか。 ただ、grep -n rev が単に順番に番号をつけるだけの目的で、revがすべての入力にあるのなら nl とかを使った方がよいかもしれません。 あるいは 'FNR==2{print ++i, ARGV[i], $0}' みたいにするとか。 きちんと桁揃えとかをしたいのなら 'FNR==2{++i; printf "%3d: %s %s\n", i, ARGV[i], $0}' とprintfを使ってもいいと思います。 その辺はお好みで。

Piranha
質問者

お礼

早い回答有難うございます! 大満足! です。 隅々と教えて頂いて感謝してます。 'FNR==2{++i; printf "%3d: %s %s\n", i, ARGV[i], $0}' が好みです。 お世話になりました。

その他の回答 (2)

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

あー、これだからSunOSのawkは(笑) とりあえずnawk 使ってください。 SunOS リファレンスマニュアル 1 : ユーザーコマンド: awk(1) http://docs.sun.com/app/docs/doc/819-1210/6n3j74jkq?a=view SunOS リファレンスマニュアル 1 : ユーザーコマンド: nawk(1) http://docs.sun.com/app/docs/doc/819-1210/6n3j74jqq?a=view awkだと、FNRやARGVを組込み変数として持ってません。

Piranha
質問者

補足

> とりあえずnawk 使ってください。 good! ばっちりでした。 > awkだと、FNRやARGVを組込み変数として持ってません。 という事は、もう " awk " は不要ってことで、全て " nawk " でやっちゃっていきます。 ・・・・で問題ないいんですよね? ところで、" nawk " の " n " は、" new " の頭文字なんですかね。 (どうでもいいですが) >> 欲を言えば、行数も出力させたいです。 > この行数というのはファイル全体で何行あるかということですか? 欲をかいて、冷静さをうしなっていたのか、↓これでいいかな。っと思ってます。 nawk 'FNR==2{print ARGV[++i], $0}' *.txt | grep -n rev 「 ブサイクだ 」と言われてしまうのでしょか。 助かりました。

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

とりあえず最初の希望だけ。 awk 'FNR==2{print ARGV[++i], $0}' *.txt > 欲を言えば、行数も出力させたいです。 この行数というのはファイル全体で何行あるかということですか?

Piranha
質問者

補足

ご協力ありがとうございます。 "awk"について色々学べました。 この機会に"組込み変数"と云う存在も知りました。 以下のように結果・・・ # pwd /***/**/** # bash # ls -l | awk '{ print $1 , $6 , $7 ,$9; }' | head -6 合計 -rwxrwxrwx 11月 13日 001.txt -rwxrwxrwx 11月 13日 002.txt -rwxrwxrwx 11月 13日 003.txt -rwxrwxrwx 11月 13日 004.txt -rwxrwxrwx 11月 13日 005.txt # cat ./001.txt hello bye hi! How are you? See you later. # # awk 'FNR==2{print ARGV[++i], $0}' ./*.txt # # awk 'FNR==2{print ARGV[++i], $0}' ./001.txt # # awk 'FNR==2{print $0}' ./*.txt # # awk 'FNR==2{print $0}' ./001.txt # # awk '{print ARGV[++i], $0}' ./001.txt hello bye hi! How are you? See you later. # # awk '{print ARGV[++i], $0}' ./*.txt hello bye hi! How are you? See you later. a b c d e A B C D E ; : ! $ . Sun Mon Tue Wed Thu # # awk -W version awk: 構文エラー (1 行目の周辺) awk: 処理を中止します。 (1 行目の周辺) # # awk --version (プロンプトが帰って来ないから<Ctrl+C>) ^C # もしかして・・・嫌な予感がするんですが、Versionが古すぎて、組み込み変数を認識してなくて駄目なんでしょうか。しかもVersionが不明ですし。

関連するQ&A

  • sedを使って複数ファイルの先頭行を表示

    以下の様なファイルがあります。 各ファイルの先頭行をとりだしたいのですが、headコマンドを使うと ファイル名と結果が分かれて表示されます。 sedで、-nオプションの行番号指定で表示することができるので、 sed -n '1p' *.txt のワイルドカード指定でやったのですが、 この場合だと複数ファイルとみてくれなくて、すべてのファイルを ひとつにしてその先頭を表示しているみたいです。 できれば、各ファイル毎に、ファイル名と結果を1行にして表示したい のですが、どうすればよいでしょうか。 参照ファイル cat 1.txt 12345 67890 cat 2.txt abcde fghij cat 3.txt 11111 22222 headコマンドで実行 $ head -n 1 *.txt ==> 1.txt <== 12345 ==> 2.txt <== abcde ==> 3.txt <== 11111 sedで実行 $ sed -n '1p' *.txt 12345

  • ファイルから1行または複数行を標準出力する方法

    ものすごく簡単な問題のような気がしますが,わかりません. コマンドで,テキストファイルから1行または複数行を標準出力する方法はありませんでしょうか? 例えば,foo.txt の10行目を出力 > line 10 foo.txt あるいは,複数のコマンドをパイプをかませて実現する方法でもかまいません. スクリプト言語すら使わないで実現できるような気がするのですが思いつきませんでした. よろしくお願いします.

  • 標準出力とファイルに効率的に同じ出力をする方法

    C&C++でプログラムしています。 (以下は、できれば、Cの範囲内で行いたいと思います。) 結果の出力を画面とファイル両方に出力しています。 printf("A"); ... printf("Z"); fprintf(fp,"A"); ... fprintf(fp,"Z"); ただし、行数が多い場合には、ほとんど同じプログラムがだぶって書いてあり、画面用50行、ファイル出力用50行で、計100行とプログラム行数も長くなってしまいます。 サブルーチン化するなどの方法で、この2つのルーチンを短く記述することは、できないでしょうか? 例えば、 画面に出力する場合には、 fprintf(fp1,"***"); ファイルに出力する場合には、 fprintf(fp2,"***"); として、どちらに出力するかによってファイル指定子を変更できると良いのですが、可能でしょうか? よろしくお願い致します。

  • 複数ファイルで、それぞれの行数をカウントして出力する

    こんにちは。 お世話になります。 早速ですが、やりたい事は・・・ 複数のデータファイルを用意しています。 それぞれに異なるデータが入っています。 そして、そのファイル毎の行数を取得し、かつそれぞれにタイトルをつけたいのです。 例) 1.txtには10行分→出力する時には「帽子:10個」 data2.txt→8行→出力する時には「植木鉢:8個」 abc.txt→30行→→出力する時には「チョコレート:30個」 ・ ・ ・ そしてそれを改行しながら出力 例) 帽子:10個 植木鉢:8個 チョコレート:30個 ・ ・ ・ ひとつのファイルに対して行数を得るのは下記の通りできました。 $f_URL="1.txt";//ファイル指定 $line=file($f_URL);//配列に $gyosu=count($line);//要素数をカウント echo "帽子:$gyosu個";//出力 ひとつひとつやればできないこともないのですが、同じ処理をやるので何かまとめて処理できる方法があるんだろうなぁ・・・とは思ったのですが・・・行き詰まりました(汗) あとできればデータファイルの内容はいじらないように使いたいのです。(1.txtの1行目にタイトルをいれておく...などは避けたいのです) もし何かよい方法があればご教授&アドバイスよろしくお願い致します。

    • ベストアンサー
    • PHP
  • ファイルから特定の行を出力したい

    あるファイルの特定の一行だけを取りだすunixの コマンドを教えて下さい。 具体的には cat a.txt 1gyoume 3gyoume 4gyoume 5gyoume 6gyoume 7gyoume 8gyoume といったファイルの末尾からX行目の内容を変数に入れたいのです。 a.txtが8行あると判断して8-X行目でファイルを分割、そのファイル をtailコマンドで末尾1行目だけ出力すると出来そうだと思ってい るのですがもっと簡単な方法はないでしょうか。

  • 標準出力しながらファイルに出力

    標準出力に表示したものを、そのままファイルに書き込むことは可能でしょうか? 例えば下記のように実現できるかと思いますが、printする度に2行書くのは厳しく思ってます。 ----------------------------- open(OUT, "> outfile.txt") ; print $aaa ; print OUT $aaa ; -----------------------------

  • grepやsed,shプログラムによるデータの整形

    grep や sed などのコマンドを使ってデータの整形をしたいと思っています。 具体的には、以下のように先頭の2字(A-Z)を「hello world」に置き換えて、 かつ全行に「 good bye」を追加したいです。 元のデータ(1.txt) を整形して 2.txt として出力し保存したいと思います。 どのようにコマンドを駆使すれば可能でしょうか。 コマンド一発でなくても shでさらさらっと書いて実現できれば それでも無問題ですので、サンプルプログラムをご提示頂けましたら大変嬉しいです。 アドバイス宜しく御願いいたします。 #元のデータ(1.txt) AA 111111.111/111 AC 22/2222222.2222 AA 33333/3333333 BB 44444.4444/444 AK 5/55555.5555 GB 66/666.666666 CC 77.7.777.77/777 #整形後のデータ (2.txt) hello world 111111.111/111 good bye hello world 22/2222222.2222 good bye hello world 33333/3333333 good bye hello world 44444.4444/444 good bye hello world 5/55555.5555 good bye hello world 66/666.666666 good bye hello world 77.7.777.77/777 good bye

  • ファイルの3行目までを出力したい

    Perl初心者です。 test.txtというファイルがあって、その中の1行目から3行目までを 出力したい場合はどうしたらいいでしょうか? open(FILE,"test.txt") || die "Open Error.\n"; @data = <FILE>; close(FILE); foreach (@data) { print $_; } これだと、ファイルの中身が全て出力されてしまいます。

    • ベストアンサー
    • Perl
  • 出力ファイル名を標準入力から指定したい。

    初心者ですが、よろしくお願いします。 perlで、data.txtというファイルへ $protein の 情報を書き込みたい場合、以下のようにすれば 良いということはわかるのですが、 open(OUT, ">data.txt"); print OUT $protein; では、出力ファイルを data.txtではなく、プログラムを 実行させる度に標準入力から指定してやることはどうやれば できるのでしょうか?

    • ベストアンサー
    • Perl
  • 標準出力と標準エラー出力を時系列にファイルへ

    例として、perlなどで、(test.plとします)  print "stdout1\n";  print STDERR "STDERR1\n";  print "stdout2\n";  print STDERR "STDERR2\n";  print "stdout3\n";  print STDERR "STDERR3\n"; このように、標準出力と、標準エラー出力が混在した状態の処理があった場合、 コマンドプロンプト(Windows2000)にて、 C:\>test.pl とすると、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のように時系列に出力されますが、これをログファイルに取ろうとして、 C:\>test.pl 1>log.txt 2>&1 とすると、 C:\>cat log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のように、標準エラー出力が先に吐き出されてしまいます。 これを画面出力時と同様に時系列で取れるようにしたいのですが、どのようにすれば良いでしょうか? 単純なことで困っています。よろしくお願いします。