複数のテキストでパスリストをフィルタリングする方法は?

複数のテキストでパスリストをフィルタリングする方法は?

複数のパスを含むテキストファイル(.txt)があり、それをフィルタリングしてパスのリストだけを残したいと思います。

ファイルは次のとおりです。

Loremipsumdolorsitametconsecteturadip"/one/path/I_want_to_keep"iscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua
Utenimadminimveniamquisnostrudexercitationul"/another/path/I_want_to_keep"lamcolaborisnisiutaliquipexeacommodoconsequat
Duisauteiruredolorinreprehenderitinvoluptatevelitess"/another/path/I_want_to_keep"ecillumdoloreeufugiatnullapariatur
Excepteursintoccaecatcupidatatnonproident"/another/path/I_want_to_keep"suntinculpaquiofficiadeseruntmollitanimidestlaborum

例に示されているパスには引用符( "")で囲まれた3つのスラッシュ(/)があり、パスの最後の部分はアンダースコア(_)で区切られた複数の単語であり、周囲のテキストには特定のパターンはありません。

私はzsh 5.8(x86_64-apple-darwin21.0)を使用しています。

答え1

私はこれを提供する:

% grep -o '"/[^"]*"' file
"/one/path/I_want_to_keep"
"/another/path/I_want_to_keep"
"/another/path/I_want_to_keep"
"/another/path/I_want_to_keep"

答え2

そしてperl

perl -lne 'print for grep m{^/.*/.*/}, /"(.*?)"/g' < your-file

引用符付き文字列の内容を抽出し(複数行にわたっていないと仮定)、/少なくとも2つの追加s `/で始まり、含む文字列を検索します。

このように入力すると

"foo"/x/y/"bar"/"/a/b/c"/"/X/Y"

つまりfoo、、、barおよび文字列の1/3だけが基準を満たしているため、/a/b/c出力のみを取得します。実際に引用符の外にあるので報告されない方法も確認してください。/X/Ygrep()/a/b/c"/x/y/"/x/y/

に言及したので、演算子で同様の操作を実行するにzshzsh、次のようにします。

set -o extendedglob
string='"foo"/x/y/"bar"/"/a/b/c"/"/X/Y"'

quoted_strings=()
: ${(S)string//(#b)\"(*)\"/${quoted_strings[$#quoted_strings+1]::=$match[1]}}

print -rC1 ${(M)quoted_strings:#/*/*/*}

どこ

  • パラメータ拡張フラグは、貪欲でない一致一致をオンにSします。${param//pattern/replacement}
  • (#b)(これを行うにはextendedglob)見積もり確認を有効にする(b一致するコンテンツ(*)で利用可能$match[1]
  • ${var::=value}拡張時にvalue(/ の Bourne シェルバリアント$var) に無条件に割り当てられます。ここでは、一致を配列に追加するために使用します。${var-value}${var:-value}$quoted_strings
  • print -rC1olumnに対応するパラメータrawを印刷します。1 C
  • ${(M)array:#pattern}catch the要素に展開されますarray(プレフィックス/サフィックスだけでなく、要素全体を完全に削除するkshの/バリアントであり、パラメータ拡張フラグはそれを復元します(削除するのではなく一致を保持します)。Mpattern${var:#pattern}${var#pattern}${var%pattern}M

関連情報