ファイル内のすべての行をgrepし、パターンマッチングポイントからファイルに行を書き込みます。

ファイル内のすべての行をgrepし、パターンマッチングポイントからファイルに行を書き込みます。

たとえば、temp.txtファイルには次の情報が含まれています。

adsf on line jhkjhvjdbvjvbvbdjkvn  
qerwtt on line fdgdgdgdd  
qwqertg on line safffasffaf  
wrt on line adaddsd

on lineファイルのすべての行をgrepし、残りの行を別のファイルに書きたいです。つまりtemp.txt、ファイル処理後、新しいファイルには次のものを含める必要があります。

on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd  

Linux端末でこれをどのように実行できますか?

答え1

-oオプションを使用grepして必要な部分のみを選択してください。あなたの場合は、パターンを使用して行の先頭から行の終わりまでをon line .*選択します。on line

% grep -o 'on line .*' temp.txt >new.txt

% cat new.txt 
on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd

答え2

viこの質問のタグと自動ファイル編集を見つけたという事実を考えると、POSIX 互換exコマンドsedこのサイトのアドバイスは、さらに Perl に対する膨大な量のアドバイスに比べてぬるま的です。awk以下は、必要なフィルタリングを実行するPOSIX準拠のコマンドです。grepex

ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output
q!' input

gコマンドに新しい行が含まれていることに注意してください。ただし、グローバルコマンドを終了する明示的な方法が他にないため、これは完全なPOSIX移植性に必要です。最大実装は複数の-cコマンドを受け入れます。この場合、次の1つのライナーが同じように機能します。

ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output' -c 'q!' input

exこのコマンドには正規表現魔法と-command魔法がたくさんありますが、よくex知られていないようなので、各部分を説明します。

-sサイレントモードで起動してex「バッチ準備」を行うため、端末に何も出力されません。

-c「ファイルを開くときは、次のコマンドを実行してください。」を意味します。 (input開こうとしているファイルの名前です。)

コマンドex自体は実際には2つのコマンドです。

g/.*\(on line\)/s//\1/ | .w!>>output
q!

g「グローバル」コマンドとは、「指定された正規表現(残りの行)に一致するファイルのすべての行で次のコマンドを実行します」を意味します。

与えられた正規表現は、.*\(on line\)「0を含む任意の数の文字の後に「オンライン」が続くもの」を意味するものです。括弧は、後で逆参照のために「オンライン」をキャプチャするために使用されます。

実際、gコマンド自体はこれと同じであり、g/on line/同じように動作します。しかし、s私が書いた代替コマンドは以下を使用します。何もない正規表現の場合、s//これは「最後に使用した正規表現の再使用」を意味します。次に、コマンドsを使用して\1テキストを置き換えます。この場合、「オンライン」を意味します。

|コマンドのパイプシンボルは、exシェルのようにパイプを表しません。彼とは対照的に、通常別々の命令を分離するために使用され、ex各命令は逐次的であるが独立して実行される。ただし、gグローバルコマンドは例外です。グローバルコマンド内では、垂直バーがすべてのコマンドを区別します。以内にグローバルコマンド - つまり、そのコマンドのみを実行します。正規表現に一致する行でグローバルコマンドで指定されます。

この場合、垂直線の後の命令はw儀式命令である。このアドレス指定子がない場合は、「現在行」を指定する点が前に続きます.。書き込みコマンドは書き込みを実行します。みんなファイル、現在の行に関係なく。 (グローバルコマンドでwriteコマンドを使用するため、ドットを省略するとwriteコマンドが一致する行には置換コマンドが実行されます。 )

これは>>、「ファイルがすでに存在する場合はエラーを発生させるのではなく、ファイルに追加する」ことを意味します。ファイルに何度も書き込むため、これが必要です。それ以外の場合は、次のように終了します。最後出力ファイルに書き込む行です。!上記の>>意味は、「ファイルいいえすでに存在する場合は、エラーを発生させるのではなくファイルを生成し、そのファイルに書き込みます。 (そうでない場合、!POSIXではこれが起こるかどうかは指定されません。)そしてもちろん、output書き込むファイルの名前も同じです。

もちろん最後に、q!「現在のファイルへの変更を保存せずに終了」を意味します。ファイルの複数行を置き換えましたが、inputこれらの変更を保存したくないので、を使用してくださいq!


次のような他の同等の方法があります。

ex -sc '%s/.*\(on line\)/\1/e | v//d
w output | q!' input

ただし、これはePOSIXでは利用できない代替コマンドのフラグを使用します。 (このフラグを省略すると、.*\(on line\)ファイルに正規表現が見つからない場合はバッチ処理が停止します。)


もちろん、どこでex 本物シャインが入っています。所定の位置にファイルの編集。ただし、上記のように、あるファイルを別のファイルにフィルタリングするために確実に使用できます。

答え3

この試み:

grep -o 'on line .*' temp.txt > out.txt

この-oパラメータを使用すると、grepは目的の行の一致する部分のみを出力します。

答え4

grepこのオプションをサポートしていない場合-o:

sed 's/^.*\(on line\)/\1/' temp.text > out.txt

または、以下を含む行が必要な場合on line

sed -n 's/^.*\(on line\)/\1/p' temp.text > out.txt

複数回発生すると、次on lineから始まる行の一部が印刷されます。一番右そんなことが起こる。一番左のアイテムの場合:

sed '/on line/!d;s//\
&/;s/.*\n//' temp.text > out.txt

関連情報