• ベストアンサー

【Cシェル】ファイルの切取り/挿入方法

Cシェル初心者です. 下記のようなファイルで"begin BBB"~"end"を切り取って(※(1)) いろいろ編集し、元のファイルの中に戻したい場合(※(2))の手順って どのようにしたらよいでしょうか? (1)切り取り方法の質問  ($1==begin、$2==BBBからendまでの切り取り) (2)編集後のファイルの挿入方法の質問。  (ファイルの途中への挿入方法) 以上、2点のご教授よろしくお願いします。 尚、環境はSolalis2.6です。 %cat file.txt begin AAA ・ ・   begin BBB   ・   ・   end ・ ・ end

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

  • ベストアンサー
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.4

シェルのビルトインだけですか~あ。ちょっとしんどいかな。 (1)切り取りコマンド #! /bin/csh -f # 起動方法 cmd fname # begin BBB から end までを fname で示されたファイルに出力する。 set FNAME = $1 set INPUT = $< while ( "$INPUT" != "" )  set CHECKBEGIN = `echo $INPUT | grep 'begin BBB'`  if ( "$CHECKBEGIN" != "" )   set FILEOUT  endif  if ( $?FILEOUT )   echo $INPUT >> $FNAME  endif  set CHECKEND = `echo $INPUT | grep end`  if ( "$CHECKEND" != "" )   if ( $?FILEOUT )    unset FILEOUT   endif  endif  set INPUT = $< end (2)挿入コマンド #! /bin/csh -f # 起動方法 cmd fname # begin BBB から end までを fname で示されたファイルで置き換える。 set FNAME = $1 set INPUT = $< while ( "$INPUT" != "" )  set CHECKBEGIN = `echo $INPUT | grep 'begin BBB'`  if ( "$CHECKBEGIN" != "" )   set EXCHANGE  endif  if ( $?EXCHANGE )   if ( ! $?FILEOUT )    cat $FNAME    set FILEOUT   endif  else   echo $INPUT  endif  set CHECKEND = `echo $INPUT | grep end`  if ( "$CHECKEND" != "" )   if ( $?EXCHANGE )    unset EXCHANGE   endif  endif  set INPUT = $< end 試してはいません。 空白が連続していると正しく出力できませんが、とりあえず。 どちらも標準入力から読みますから cmd fname < original_file のように起動して下さい。

lts107
質問者

お礼

ありがとう御座いました。

その他の回答 (4)

回答No.5

まあ、シェルだけでやるというパズルは置いといて ^^ begin BBB -- end 間に他の end がないという前提ですね。 その間に限定した文字の置換でよければ、 sed -e '/begin BBB/,/end/s/前/後/' で実現できます。 1行に複数個置換対象があるなら、最後に g をつけます。 他のパターンもあれば、同じように並べれば済みます。 置換されたファイルが file として既にあるなら、 sed -e '/begin BBB/r file' -e '/begin BBB/,/end/d' となります。 もし、一旦、該当部分をファイルとして取り出す必要があるなら、 sed -n '/begin BBB/,/end/p' >fff で取り出し、変更してから、上のようにしてやればOKです。 ここまでの程度であれば、awk は出てこなくても大丈夫でしょう。

lts107
質問者

お礼

ありがとう御座いました。

  • mph
  • ベストアンサー率54% (39/72)
回答No.3

Cシェルでって言っている以上、Cシェルのビルトインコマンドのみで実現したいのではないでしょうか? exやsedを使ったらshellだけじゃないっすよね。 {意地の悪い読み方 :-P } shellのみでは私は実現不可能かきわめて困難とおもいます。 私自身はawk使いなので単純な作業ならawk,そうでないならperl最後はyacc(bison)の順番で考えるとおもいます。 shellでの実装は最初から考えないです。 まあ、どちらにせよbeginとendの部分の詳しい構文ルールといろいろ編集の部分のやりたいことがわからないと最適なツールと実装方式は紹介できませんね。

lts107
質問者

お礼

ありがとう御座いました。

回答No.2

いくつかの具体的な条件がわからないと、正確な解は出せないです。 begin BBB と、それに対応する end の間に、他の end が入ったりはしないで しょうか?あるいは、対応する begin と end の字下げは確実に同じでしょう か? 編集とは具体的に何をするのでしょうか?あらかじめ用意してあるものと取り 替えるのか、内容を見て機械的な処理をほどこすのか。 簡単な場合には sed だけでできたり、ed へのコマンドを適当に並べてやれば できたりもします。複雑になれば、awk や perl を呼ぶ必要があるかもしれま せん。 複雑な構文規則があって、どんな場合にも完璧に対応させたいとなると、perl でも荷が重くて、C と yacc になったりします。 やりたいことの具体的な中身しだいです。

lts107
質問者

補足

説明不足ですいません。 補足しますので、またご教授願います。 >begin BBB と、それに対応する end の間に、 >他の end が入ったりはしないでしょうか? 入りません。 -- >あるいは、対応する begin と end の字下げは確実に同じでしょうか? 字下げは不確定です。 -- >編集とは具体的に何をするのでしょうか? 今回は、文字の置換を行います。 編集内容は、sed等を用いてすでにできています。 ただ、今後応用できるように略式で書いてみました。 -- >複雑になれば、awk や perl を呼ぶ必要があるかもしれません。 perlは全く知りませんが、awkは少し使えるので awkで説明していただければ幸いです。

  • ojin
  • ベストアンサー率43% (280/638)
回答No.1

cat、moreはエディターではないので、カットアンドペーストはできるのかなあ? viであれば、 "ESC"キー > : 移動開始行 移動終了行 m 移動先行 で出来るとおもうのですが。

lts107
質問者

補足

有難う御座います。 シェルスクリプトでの編集方法を ご教授いただけると嬉しいのですが・・・

関連するQ&A

  • ファイル中の数行を抜き出す処理について(シェル)

    ファイルaaa.txtの2行目から4行目を抜き出し、 ファイルbbb.txtに格納する方法として、 sed -n '2,4p' aaa.txt > bbb.txt がありますが、 変数を使用し、 start=2 end=4 sed -n '${start},${end}p' aaa.txt > bbb.txt とすると、エラーが発生します。 どうすればよろしいのでしょうか。

  • Cシェルでテキストファイルの行削除方法

    現在、Cシェルの勉強をしていますが、ある文言に完全一致した行のみ削除する方法が分かりません。 例として、下記のようなファイルがあり、"AAA"を指定して削除しようとすると、"AAA_1"までも削除されてしまいます。 例)test.txt AAA aaa AAA_1 aaa BBB bbb CCC ccc お手数ですがご教授いただけると幸いです。 以上、宜しくお願い致します。

  • シェル:大量の比較方法に困ってます

    ファイル容量毎にフラグを付与したいと思ってます。 しかし、区分けが多いので判断する方法がわかりません。 例) 容量 ファイル名 13   aaa.txt 53 bbb.txt 153 ccc.txt 800 ddd.txt 1200 eee.txt ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 容量 ファイル名 フラグ 13   aaa.txt  0 53 bbb.txt 500 173 ccc.txt 1500 830 ddd.txt 8000 1220 eee.txt 10000 【判断基準】 容量   フラグ 1~50   0 51~100  500 101~150 1000 151~200 1500 201~250 2000  ・  ・  ・ 4901~4950 40000 4951~5000 45000 最終は5000まで判断させたいのですが記述方法がわかりません。 少ない判断でよければ cat aaa.log | awk 50<$2 '{print $2,"50",$3}' | awk $2<100 '{print $2,"50",$3}' な感じで挑戦してみたのですが・・・・。 ご教授お願いします

  • unixのシェルでファイル内容を読み込む

    ど初心者です。わかりづらいかもしれませんが宜しくお願いします。 以下のような処理を行いたいと考えています。 (1) aaa.sh(シェルスクリプト)にてバッチプログラムを起動 (2)バッチでエラーの場合、結果ファイル(bbb.txt)に「1」を出力する。 (3)aaa.sh(シェルスクリプト)にて結果ファイルの内容を読み取り「1」の場合は、再度バッチプログラムを起動する。 このうち(3)の処理にて、結果ファイルの読み込み方法がわかりません。 調べた結果、以下のような処理で可能なようですが・・ while read LINE; do echo $line done < aaa.txt 読み込むのは1行なので、ループ処理にはしたくないのですが、例えば「read LINE aaa.txt」のような簡単なコマンドで、ファイルの中身を読み込むことはできないのでしょうか? 実はUNIXが初めてで、しかもスケジュールに余裕がないため焦っております。 なにぶん知識不足な故、ちんぷんかんぷんな質問かも知れませんが、よろしくお願いいたします。

  • 二つのファイルから一行ずつ取り出して計算

    aaa.txt と bbb.txtというファイルがあり、それぞれ 1.1 0.1 -0.2 0.9 … といった感じで一行ずつ数値が入っています。 シェルスクリプトを用いて、 この二つのファイルから一行ずつ取り出して足し算を行いたい (例えばaaa.txtの一行目が1.1、bbb.txtの一行目が0.9なら1.1+0.9=2.0) のですが、どうすれば良いでしょうか。

  • シェルスクリプト(bash)によるファイルの編集

    シェルスクリプト(bash)によるファイルの編集についてのご相談です。 私にあまりスクリプトの知識がないので申し訳ございませんが、 どなたかお知恵を拝借させてください。 よろしくお願いします。 【条件】 ・以下のような文字列を含むファイルが複数あるとします。 ・そして、その文字列は、ファイル内の不特定の行に存在します。 ※[半角スペース]、[タブ]は実際には便宜上記載していますが、実際は 本当の半角スペース、タブが入ります。 AAA[半角スペース]BBB AAA[半角スペース]CCC AAA[タブ]BBB AAA[タブ]CCC 【やりたいこと】 このとき、 AAA[半角スペース]BBB および AAA[タブ]BBB の行の下に、それぞれ、 AAA[半角スペース]DDD  と   AAA[タブ]DDD を挿入したいのですが、これをスクリプト(コマンド)でどのように行えば よいのかわからずに困っています。

  • Cシェルでのファイル編集について

    Cシェルについて、すみませんが教えてください。。 AAA,BBB,1 1,data1,0000 2,data2,0000 3,data3,0000 4,data4,0000 ・・・ CCC,15,2,13 上記のようなヘッダ1行+データN(ここでは13行とする)行+トレイラ1行で 構成されているファイルがあり、このヘッダとトレイラを以下のようなファイル に加工するプログラムをCシェルで作成したいのですが、全く見当がつきません。 AAA,BBB,00001 1,data1,0000 2,data2,0000 3,data3,0000 4,data4,0000 ・・・ CCC,00015,00002,00013 ※ヘッダの3項目めを5桁になるように左0埋め ※トレイラの2項目めを5桁になるように左0埋め ※トレイラの3項目めを5桁になるように左0埋め ※トレイラの4項目めを5桁になるように左0埋め どなたか教えてください。よろしくお願いいたします。

  • シェルでファイルの最下行を削除する方法

    シェルでファイルの最下行を削除する方法 シェルで、ファイルaaa.txtの最下行を削除したいです。これを1行で実現したいです。 exには-cってオプションがあるので、ex -c '$d' aaa.txt などと試してみましたがダメでした。 ;(コロン)や&&でつなぐのは、1行ではないって事でお願いします。 >cp aaa.txt tmp && sed '$d' tmp >aaa && rm tmp #こういうのは無しって意味です。 事前にスクリプトや、それ専用のバイナリを用意しておくのも無しでお願いします。なるべく汎用的な どこのUNIXにでもあるようなコマンドで実現したいです。

  • C言語でのファイル検索&ファイル書き換えについて

    C言語である特定のフォルダを指定して、その階層内(サブフォルダも含む)にあるファイル、例えばsample_nameをファイル名に含むファイルを見つけ、そのファイル内の例えば下のような書き換えを行えるようなプログラムはどうつくればいいのでしょうか。 元ファイル ~sample_name1.txt~ aaa, 10 bbb, 20 ccc, 30 ~sample_name2.txt~ aaa, 30 ccc, 12 bbb, 20 ddd, 15 上のように各ファイルにaaaやbbbが共通に含まれています。 対象ファイル:sample_name 対象文字列:aaa 変換後:100 変換後ファイル ~sample_name1.txt~ aaa, 100 bbb, 20 ccc, 30 ~sample_name2.txt~ aaa, 100 ccc, 12 bbb, 20 ddd, 15

  • シェルスクリプトの引数について

    test.sh '*.c' といったコマンドを入力した時に、 シェルスクリプト内で引数$1を受け取ったときに$1='*.c'となるのではなく、 カレントディレクトリ内にある'*.c'の正規表現にマッチするファイルが入ってしまっています。 例)カレントディレクト内にaaa.cファイルbbb.cファイルといったファイルがある時は、 $1=aaa.c bbb.cとなっています。 '*.c'の正規表現自体をシェルスクリプト内で受け取る方法はないのでしょうか? シェルはbashを使用しています。