質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
sed

sedとは、POSIX環境のために作られたコマンドラインエディタです。sedは編集スクリプトの指示のもとに複数のファイルを編集し、標準出力にその結果を出力します。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

Q&A

解決済

1回答

1076閲覧

複数ファイルに対して指定文字列が最初にマッチした行の2行後から最終行までを削除したい

yrk

総合スコア6

sed

sedとは、POSIX環境のために作られたコマンドラインエディタです。sedは編集スクリプトの指示のもとに複数のファイルを編集し、標準出力にその結果を出力します。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

0グッド

0クリップ

投稿2020/04/04 16:35

編集2020/04/05 09:40

(2020/04/05 18:30旧タイトル[複数ファイルに対して指定文字列が含まれる次の行以降を削除したい]から修正)

複数ファイルに対して指定文字列が最初にマッチした行の2行後から最終行までを削除したい

あるディレクトリに複数個ある指定書式のテキストデータを、条件に合わせて一括置換したいと考えています。
###テキストの形式

20160101 Sapporo 20160302 Utsunomiya 20160422 Morioka 20160812 Sendai 20161111 Tsu 20161221 Mito 20170106 Koufu 20170505 Takamatsu ︙ 20191030 Matsue 20191231 Nagoya 20200111 Matsuyama 20200303 Naha 20200311 Nagoya 20200401 Maebashi 20211231 Yokohama 20210303 Ootsu ︙

このような日付 都市が一行おきにあるsample.txtの最初に1231が~~(18:30修正)ヒットした次の行以降~~マッチした行の2行後から最終行までを削除したく、
この例ですと20200111 Matsuyama以降を削除したいです。
(15:49追記)1231の次にどの日付が来るかはランダムです。

試したこと

1, find . -name "*.txt" | xargs sed -i "/1231/,$ d"
20191231 Nagoya から削除されてしまう

2, find . -name ".txt" | xargs sed -i "/1231/a Insert"
で、20191231 Nagoyaの次の行に削除用の行を挿入、その後
find . -name "
.txt" | xargs sed -i "/Insert/,$ d"
で削除用行以下を一括削除
20200111 Matsuyama が残らない

3, sed -i "$((sed -n '/1231/=' test.txt + 2))i\Inserted." test.txt
で20200111 Matsuyama の次行にInsertの挿入を試みる。単一のファイルに対して実行できたが、複数ファイルに適応しようと
find . -name "*.txt" | xargs sed "$((sed -n '/Nagoya/=' *.txt + 2))i\Inserted."
を行うと
bash: 181
419 + 2: 式に構文エラーがあります (エラーのあるトークンは "419 + 2")
とエラーが出る。

(15:49追記)
4, cat test.txt | sed -e "/1231/,$ d" -e "/1231/,+1p"
削除が先に行われるのでマッチする行+1行を出力が反映されなかった。

(18:30追記)
5, find . -name "*.txt" | xargs sed -i "/1231/q"
20200111 Matsuyama が残らない、複数ファイルに適応時に1ファイルしか変更が反映されない。

環境

Ubuntu 16.04 LTSで実行しています。
上記はググッて見つけた例をの試行錯誤で切り貼り・改変してみたものです。
実行可能な方法があればsed以外でも大丈夫です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

sh

1sed -n 1,/1231/p

#追記
マッチした2行後以降を削除する場合。

sh

1sed '/1231/{n;q}' 2 3sedによっては、こう書かないといけないかも。 4sed -e /1231/{ -e n -e q -e }

投稿2020/04/04 17:15

編集2020/04/05 08:59
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yrk

2020/04/05 06:48

回答ありがとうございます。実行してみたのですが、20191231 Nagoyaまで表示されたものの、20200111 Matsuyama が残りませんでした。1231にマッチした行の2行後から削除したいです。 表現不足ですみません。
otn

2020/04/05 08:10 編集

タイトルや質問文は嘘ということですか? > 指定文字列が含まれる次の行以降を削除したい > この例ですと20200111 Matsuyama以降を削除したいです。
yrk

2020/04/05 08:37 編集

> タイトルや質問文は嘘ということですか? 確かにそう読み取れますね、すみません。「X以降」という表記を、「Xから」でなく「Xの次の項目」という認識で書いていました。 「指定文字列が含まれる次の行(+1行)以降(更に+1行)を削除したい」という意図でした。 「指定文字列が最初にマッチした行の2行後から最終行までを削除する」という質問なら問題ないでしょうか。
otn

2020/04/05 08:55

ああ、「以降」という言葉の意味を知らなかったということですね。 了解です。 「明日以降受け取りに来てください」と言われたら、明日行っても大丈夫です。 > 「指定文字列が最初にマッチした行の2行後から最終行までを削除する」という質問なら問題ないでしょうか。 はい。
yrk

2020/04/05 09:57

追記回答ありがとうございます。 このコマンドをfindとxargで配下のtxt全部に実行したところ、1ファイルしか変換されていませんでした。 複数ファイルに対して実行する方法はありますか。
otn

2020/04/05 10:04

xargs -n 1 sed '/1231/{n;q}' で。
yrk

2020/04/05 10:45

無事できました。 勉強になりました、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問