• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:grep,sedコマンドについて)

grep,sedコマンドについて

このQ&Aのポイント
  • grepコマンドとsedコマンドを使用してファイルの数字と時間の部分を削除する方法について質問します。
  • grepコマンドで削除部分を抽出し、sedコマンドで行を削除する方法を検討していますが、具体的な方法がわかりません。
  • 質問した内容について、grepコマンドとsedコマンドを組み合わせて適切に行削除を行える方法を教えてください。

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

  • ベストアンサー
  • ky072
  • ベストアンサー率60% (85/140)
回答No.2

元のファイルを SRC.txt とします。 (a) sed はデフォルトでは複数行を読み込みません。 Nコマンド等で次の行をパターンスペースに読む必要があります。  % sed '/^[0-9][0-9]*$/{N;/[0-9][0-9]*\n[0-9][0-9].*/d}' SRC.txt (b) [0-9]* を [0-9]+ にすれば解決します。 * は 0 文字にもマッチするため、 「10」の上の空行にマッチしていると思われます。 (c) 通常、複数行にマッチするような正規表現は grep で使いません。 -P オプションを付けた場合のみ、改行にマッチさせられるようです。 (d) 懸念されている「数字のみの台詞行」を無視するなら、 grep で簡単にできます。 % egrep -v '^([0-9]+|[0-9:, ]+-->[0-9:, ]+)$' SRC.txt 厳密にやりたいなら awk や perl がおすすめです。 % awk '{if(/^[0-9:, ]+-->[0-9:, ]+$/&&b~/^[0-9]+$/){getline;b=$0;getline;}print b;b=$0;}END{print b}' SRC.txt

airrace
質問者

お礼

回答ありがとうございます >% sed '/^[0-9][0-9]*$/{N;/[0-9][0-9]*\n[0-9][0-9].*/d}' SRC.txt これでは出来ませんでしたが、 $ sed 'N;/[0-9]\+\n[0-9][0-9].\+/d' で、ある程度は削除できましたが、いくつか残ったままのところもあります >[0-9]* を [0-9]+ にすれば解決します。 おっしゃる通りで、見事解決しました(^^) >厳密にやりたいなら awk や perl がおすすめです。 どちらもまだ知りませんが、おいおい習得しようかと思います。 sedコマンドで成功させるにはどうしたらよいのでしょうか? grep -P "^[0-9]+\n[0-9][0-9].+"では削除対象の行が正しく表示されます

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

単に「できない」というのではなく, 何がどう「できない」のかを書いてもらえませんかね. N で追加する文字列が「削除すべき 1行目」だったりすると問題になりそうですが, そういうことですか?

airrace
質問者

お礼

はじめに 色々触っていたら以下のコマンドで遂に成功しました。 sed '/[0-9]\+/N;/[0-9]\+\n[0-9][0-9].\+/d' >単に「できない」というのではなく, 何がどう「できない」のかを書いてもらえませんかね. 自分でもそれが分かりませんでした。と言うのも、 sed 'N;/[0-9]\+\n[0-9][0-9].\+/d' を行ったとき、(自分が見る限りでは)不規則に、成功する行(数字のみの行と時間の削除) と成功しない行があったので。

  • pakuti
  • ベストアンサー率50% (317/631)
回答No.4

難しく考えないで grep -v "^[0-9]\+" |grep -v "^[0-9][0-9]:" で、事足りるのでは?

airrace
質問者

お礼

回答ありがとうございます はい、おっしゃる通りで、そうすれば必要な部分のみを表示させることが出来ますね ただ、台詞が数字の時は表示されませんが・・・ あっ、この投稿をみて閃いたのですが 必要な部分(台詞で数字のみの部文も)をgrepで取ってリダイレクトすればいいのか!! grep -v -P "^[0-9]+\n[0-9][0-9].+" 入力ファイル >> 出力ファイル で、出来ました(^^) でも、なんでsedでは出来ないんですかね?もう少しだと思うのですが

回答No.3

問題点をあげると、 まず正規表現を渡すとき、シェルの変数をつかわないかぎりは、""ではなく''で囲った方がいいです。 ''は囲まれた文字列をそのままgrep やsedに渡してくれるので、ワイルドカードとして当てはまるからと、 シェルに改変されずにすみます。 つぎに、sedやgrepは基本は行単位で一行ずつ読み込みをして改変するということです。 /[0-9]*\n[0-9][0-9].*/などは2行におよんでいるために理解してもらえません。 (もしかしたら行単位でなく読み込んだりできるのかもしれませんが、自分は詳しくなくて、、すいません。) なのでこの場合、数字だけの行を消すのと、数字と:が混じった行を消すのとで二つ分正規表現を書きます。 あるいは、アルファベットが含まれない行だけを出すという表現なら一つの表現でも大丈夫です。 (もしかしたら、最初の数字だけの行を消したあと必然的にその下の行を消すなんて表現もあるかもしれませんが、すいません、自分の勉強不足ゆえに分かりません。。。) また、後半の.*ですが、これは指定してもしなくても代わりありません。 sedのdは、マッチした行そのものを消すわけですので、.*以前の[0-9][0-9]でマッチすればその行を必然てきに行全体を消してしまいます。 *などを利用するのはdで○○しかない行をとか、sの変換置換で、ここまでを置換するという範囲指定のときに使われます。 sedを使うならば、 $ sed '/^[0-9]*$/d;/^[0-9][0-9]:/d' hoge.txt でしょうか。 一応説明すると、 '/^[0-9]*$/d' と '/^[0-9][0-9]:/d'というのを;でつないで 連続して行うようになってます。 最初のは、行が数字のみを削除するを表し、 次のは、先頭に数字二回のあと:がくる行を削除をしめしてます。 grep で行うならば先言ったアルファベットが含まれる行を表示として、 $ grep '[a-zA-Z]' hoge.txtとか、 $ grep '[[:alpha:]]' hoge.txtとか、(これはアルファベットすべてを表すクラスという表現) ですね。 (grep にも正規表現に当てはまらない行のみを表示するというあまのじゃくな-vオプションというのがあり、 これをつかえば、sedのように該当行のみ表示させないとできますが、 今回は該当行のみ表示させないと表現するのに二つ正規表現が必要で、 grepに条件を復数していする方法は、自分、くわしくないのですいませんわかりませんでしたので載せません。) grep や sed を使うときは、 それらが基本は行を一行ずつ処理していくということを 頭において考えるとうまくいきます。 そして、正規表現ですが、 馬鹿みたいにたくさん種類がありますので、 基本使いそうなものをいくつか覚えておくと便利です。 こういうコマンドって便利なのでぜひ頑張ってください。

airrace
質問者

お礼

回答ありがとうございます >$ sed '/^[0-9]*$/d;/^[0-9][0-9]:/d' hoge.txt 実行しますと、確かに「数字のみの行」と「時間の行」は削除できますが 「台詞が数字のみの行」も削除されてしまいます。 あと、なぜか空白行 n 時間 台詞      ←(ここです) n+1 時間 ・ ・ も削除されてしまいます。 自分は sed 'N;/[0-9]\+\n[0-9][0-9].\+/d' を適切にいじれば解決すると思うのですが・・・

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

sed ならできそうな気もするけど, perl があるならそっちの方がはるかに楽.

airrace
質問者

お礼

回答ありがとうございます perlを使ったことがないので・・(汗)

関連するQ&A