grepとsedの正規表現

grepとsedの正規表現

テキストファイルでaで始まるすべての行を見つけて置き換えようとしています。シングルスペースだから誰のキャラクターも。

最後にgrepで動作する正規表現を得ました。grep -E '^ .*$*' Contacts.vcf >> t.txt

その後、sedで使用するときはそうではありません。sed 's/^ .*$//g' Contacts.vcf > tt.txt(最初のスペースに関係なく)すべての行を取得します。\s{1}全部入れてみましたが、()実行できませんね。

初めてWindowsでPowerShellを使用しようとしたときも、同じ問題が発生しました。クロスプラットフォーム正規表現の詳細(?)がありません。

正規表現で単一のスペースで始まる行のみを検索するにはどうすればよいですか?

答え1

grep「空白で始まり、後ろにランダムな文字が続きます」を実装することで単純化できます。

grep '^ .'

「空間で始める」としたら、簡単です。

grep '^ '

sed多様性すべてを入力して表示します。sedもう少し同様に動作するには、フラグとコマンドが grep必要です。これは、デフォルトでは出力を表示しないことを意味し、「この行を印刷します」を意味します。-np-np

例えば

sed -n '/^ /p'

同様に、スペースで始まるすべての行を表示します。

sed -n '/^ ./p'

スペースで始まり、その後に他の文字が続くすべての行を表示します。

編集する

他の意見によると、あなたの目標はスペースで始まる行を削除するようですsed

この場合

sed -i '/^ /d'

デフォルトでは、「スペースで始まる行を検索して削除」します。

例えば

$ cat x
hello
 there
everyone

$ sed -i '/^ /d' x

$ cat x
hello
everyone

答え2

スペースで始まるすべての行を削除したい場合。

次のコマンドでgrepを使用できます-v

grep -v -E '^ .*$' Contacts.vcf > tt.txt

   -v, --invert-match
          Invert the sense of matching, to select non-matching lines.

また、「$」は行の終わりを示します。

その後に文字があってはなりません。

したがって、「$」の後のアスタリスクは意味がありません。

答え3

あなたは言う:

単一のスペースで始まり、任意の文字で始まるテキストファイルのすべての行を見つけて置き換えようとします。

リストされた項目の正規表現構文を追加すると、次のようになります。

^単一のスペース()で始まり、その後にランダムな文字(技術的には ..*BREまたは.+EREではありますが、1文字は「すべての文字」なので)で始まるテキストファイルのすべての行を見つけて置き換えようとします。 print 一致する特定の文字列を印刷する代わりに、一致する文字列の完全な行を含みます。.正規表現だけで済みます。

次に、これらのツールのすべてのバージョンを使用して、次のように直接実装します。

grep '^ .'
sed -n '/^ ./p'
awk '/^ ./'

から:

  1. ^=文字列の先頭(この場合は現在の入力行)。
  2. =スペース。スペース文字を意味する場合は、スペースまたはタブ文字のみを意味する場合、または[[:space:]]または[[:blank:]]を使用してください。[ \t]
  3. .=ランダムな文字。

使用するコマンドはgrep次のとおりです。

grep -E '^ .*$*'

次の問題があります。

  1. -Egrepデフォルトの BRE の代わりに ERE を正規表現として受け入れますが、正規表現にはデフォルトの正規表現構文以外の項目がないため、役に立つ-E操作は行われません。
  2. $バッファの終わり(この場合は入力行の終わり)を表しますが、メタ*文字が0個以上繰り返されるので、$*「バッファの終わりが0個以上繰り返される」ことを意味します。定義によっては、終わりは1を超えることはできません。したがって、処理されるバッファは意味がなく、事実上POSIXに基づいて定義されていない動作です。
  3. .*「文字が0個以上繰り返される」を意味しますが、その位置に文字が1個以上ある必要があるという要件があるため、これは*間違っています。.+ERE または BRE で「1 つ以上」を意味するために使用できますが、要件に 1 文字だけで..*十分であるため、「またはそれ以上」は必要ありません。.つまり、1つ以上の文字が必要です(1つで十分です)。
  4. .*スペースの後ろのどの文字とも一致しませんが、「すべての文字」は少なくとも1文字を意味すると仮定します。

使用するコマンドはsed次のとおりです。

sed 's/^ .*$//g'

次の問題があります。

  1. grepとsedはどちらもデフォルトでBREで実行されます-E。 grep regexpが必要だと思われる場合は-E(必要ありません)、-Esedを使用して呼び出す必要があります。
  2. grep 正規表現*の終わりにあります。繰り返しますが、grepに必要だと思われる場合(そうではありません)、sed regexpにも必要です。
  3. grep正規表現のように、空白の後ろに文字を許可したくない.*$場合は動作しますが、それも問題ありません。..?.*
  4. grep正規表現とグローバルに一致し、結果を印刷するコマンドにちなんでg/re/p命名されました。edこれを考慮すると、基本的にgrepは正規表現に一致する行だけを印刷することは明らかです。sedストリームエディタなので、ユーザーが提供するすべてのコマンド(現在他のコマンド)を実行しますedが、他のエディタと同様に、ユーザーが指定しないと何も削除されないため、デフォルトでは各入力行が印刷されます。 。sedそれ以外の場合は-n(「デフォルトでは印刷しない」)を使用して呼び出し、スクリプトpの指示を使用して特定の行を印刷するように指示する必要があります。
  5. sedコマンドの終わりに、gsedは入力行に現れるたびに正規表現に一致するように指示しますが、行の先頭では^1回だけ一致し、行の終わり$には1回だけ一致します。正規表現は1行に1回だけ一致する可能性があるため、gsedに正規表現を複数回一致させるようにコマンドの末尾にaを入れることはお勧めできません。

その他の注意事項:

  1. sedのGNUおよびBSDバリアントのみが-EEREをサポートし、他のすべてのsedバリアントはBREのみをサポートします。
  2. 「I've try it」に関して - POSIX BREまたはERE以外の\s{1}PCREのPOSIX文字クラスの略語。 GNU sedおよびGNU grepは、BREまたはERE、YMMV、および非GNUバリアント、またはPCREの代わりにBREおよび/またはEREと連携する他のツールを許可します。\s[[:space:]]\s

関連情報