パターンまですべてを削除し、行から別のパターンの後にすべてを削除するにはどうすればよいですか?


16

次のファイル:

Lorem ipsum dolor sit amet、consectetuer adipiscing elit。Ut eu metus id lectus vestibulum ultrices。Maecenas rhoncus。

consectetuerとすべてを削除したいelit

私の希望する出力:

consectetuer adipiscing elit.

これどうやってするの?


2
コマンドは次のとおりsedです。perlまたは、純粋なbash にすることもできます。
ムル

@manuelこれらの回答のいずれかで問題が解決した場合は、しばらくしてから左のチェックマークをクリックして受け入れてください。これにより、質問に回答済みのマークが付けられ、Stack Exchangeサイトで感謝が表明されます。
テルドン

回答:


27

sedを使用します

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

sed s / find / replace /構文をデコードしました:

  • s/^.*-行の先頭から始まる置換(^)に続く任意の(.*)...
  • \( -名前付きブロックを開始する
  • consectetuer.*elit\.-最初の単語、.*最後の単語(この場合、末尾の(エスケープされた)ドットを含む)までのすべてを一致させます
  • \) -指定されたブロックを終了する
  • 他のすべて(一致.*(行末までを)$
  • / -代替検索セクションの終了
  • \1-間の名前のブロックと交換\(し、\)上記
  • / -交換を終了する

1
良い答えは、しかし、あなたは必要としない^か、$sedのため、試してみて、最長一致を検索します。また、の後のドットを見逃している可能性があります。必要に応じてelit挿入できます\.
asoundmove

2
@asoundmove "elit。"の末尾のドットをよくキャッチしてください。-あなたはかなり鋭い目を持っています!パターンにエスケープドットを含めるように回答を更新しました。また、必要^$はないことを修正します-質問者が(元々)彼は少し初心者であり、これは他の文脈で役立つかもしれないと指摘したように、私はそれらをそこに残しました。
MikeV

私はいつもsedソリューションをコピーして貼り付けて、自分のニーズに合うようにハックしましたが、この答えのおかげで、実際にそれを理解したように感じます。すばらしい答え
タイラー

6

すべての行に開始パターンと終了パターンの両方が含まれている場合これを行う最も簡単な方法はgrepです。各行の最初と最後を削除する代わりに、両方のパターン間の内容を単純に出力できます。-oGNU のオプションはgrep、一致するもののみを出力します。

grep -o 'consectetuer.*elit' file

注:前述のとおり、これは、ファイル内のすべての行をこの方法で解析できる場合にのみ機能します。繰り返しますが、これはすべての典型的なユースケースの80%です。


1

AWKの2つのforループ:

$ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n"   }' file.txt 
consectetuer adipiscing elit.

AWKのgsub:

$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.

1

Perlの方法。これは、MikeVのsed答えと本質的に同じです。

perl -pe 's/.*(consectetuer.*elit).*./$1/' file

-pは、「指定されたスクリプトを適用した後にすべての行を印刷する」という意味-eです。s/foo/bar/置換演算子です。に置き換えfooられbarます。カッコはパターンをキャプチャし、置換に使用します。最初にキャプチャされたパターンは$1、2番目$2などです。

そのため、コマンドはconsectetuer.*consectetuer)まですべてを照合し、次に()まですべてを照合し、次に行の最後までelit.*elit)を照合.*して、キャプチャしたパターンに置き換えます。


1

この質問のタイトルが「ファイルから」から「行から」に編集された理由はわかりませんが、OPは例が1行のみのように見えても、複数行にわたる可能性を除外しません。いずれにせよ、ここで複数行のソリューションを提供すると役立つ場合があります。

これはクロスラインで機能します:

from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"

例:

[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl

home

def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl

home

def elit
[xiaobai@xiaobai tmp]$ 

参照:シェルパラメーターの展開


1
それは最高です!
クレメント
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.