文字列の一致しない部分だけを印刷したいです。逆のオプションはありますかgrep -o
?grep -v
パターンを含む文字列を完全に無視するためではありません。
私が持っているとしましょう:
setenv var "/home/user/dir/subdir/case"
setenv path "/home/user/dir"
ただ戻る必要がありますが、subdir/case
簡単にできる方法が見つかりませんgrep
。
grep -o
一致する文字列部分のみを返す場合、一致しない文字列部分のみを返す負のオプションはありますか?
答え1
PerlまたはPerlを使用すると、sed
パターンに一致する行の一部を削除して残りの行を印刷できます。サンプルデータが次の場所にあるとしますfile.txt
。
$ sed -ne 's/^setenv var *//p' < file.txt
"/home/user/dir/subdir/case"
あなたが得ることを求めるのは、実際には終わりの引用subdir/case
符もあるので、2つの部分を削除する必要があります。キャプチャグループを使用すると、途中から部分を取得する方が簡単です。ここでは、セクションでは文字列のうち、このときに合う部分を保存し、(.*)
置換セクションでは一致するものをすべて置き換えるようにします。 print()コマンドは、ここでreplacement()が一致する条件に従って実行されます。パターン自体に現れるので、区切り文字として使用していますが、どの文字でも使用できます。sed
\1
p
s///
,
/
$ sed -nEe 's,^setenv var *"/home/user/dir/(.*)".*,\1,p' < file.txt
subdir/case
または、Perlは何も変更せず、一致からキャプチャされた部分のみを印刷します。
$ perl -lne 'print $1 if m,^setenv var *"/home/user/dir/(.*)",' < file.txt
subdir/case
上記の両方とも、パターンと一致しない行については何も印刷しません。
内容全体を印刷するには、無条件に印刷してください(前のセミコロンを参照p
)。
$ sed -nEe 's,^setenv var *"/home/user/dir/(.*)",\1,; p' < file.txt
subdir/case
setenv path "/home/user/dir"
または
$ perl -lne 's,^setenv var *"/home/user/dir/(.*)",$1,; print' < file.txt
subdir/case
setenv path "/home/user/dir"
答え2
正しく理解したら使えますGNU grepそしてlookbehind assertion
そしてlookahead assertion
:
# return what doesn't match 'dir/' at the end of the line
# and doesn't match the final double quote '"'
$ grep -Po '(?<=dir/).*(?="$)' file
subdir/case
dir/
これは以前の「否定的」モードを想定していますsubdir/case
。モードがフルディレクトリの場合:
grep -Po '(?<="/home/user/dir/).*(?="$)' file