使い方を理解していますpax
。
背景:.tgz
ファイルを供給しpax
て抽出し、ファイルでいっぱいのフォルダーを入手します。
私が理解していないものは次のとおりです。
pax -r -z -s '/.*\\//directory\\//p' -f $input_path/$tgz
ここでは、$input_path
パスを含むPerlのスカラー変数、$tgz
ファイル名を含む別のスカラー変数です.tgz
。
だから-r
読むのが合理的-z
で、解凍してもいいです。そして-s
ロゴが-f
私を混乱させる。次のエラーが発生します
pax: Invalid replacement string option /.*\\//directory\\//p
。
私の考えでは、フラグがどのように機能するかは次のとおりです。
-f
、これは問題にならないようです。ここにファイルが配置されます。
-s
、文字列置換はファイルに含まれるファイル名を変更します.tgz
。
/.*\\//directory\\//p
ここで何が起こっているのか、すべてのスラッシュが抜け出すことを本当に理解していないので、誰でもこの部分を理解できますか?\
そしてp
何かしなければなりませんが、何をすべきかわかりません。
答え1
Paxは/.*\\//directory\\//p
次のように決心します。
/
区切り記号です。.*\\
バックスラッシュ(バックスラッシュは次の文字を引用)で終わるすべての文字列に一致する正規表現です。/
正規表現を代替テキストから分離します。/
代替テキストを終了します。directory\\//p
ゴミを捨てているんです。
明らかにバックスラッシュを使用してスラッシュを保護し、区切り文字ではなく正規表現の一部になるようにします。シェルスクリプトには追加のバックスラッシュがあります(ただし、これはおそらくPerlスクリプトで発生する現象によるものです。詳細については後で説明します)。スラッシュにも問題があります。パスから削除するには、any/leading/prefix/up/to/directory
次のようにする必要があります。
pax -r -z -s '/.*\/directory\///p' -f "$input_path/$tgz"
別の区切り文字を使用すると、読みやすくなります。これでスラッシュを抜ける必要はありません。
pax -r -z -s '!.*/directory/!!p' -f "$input_path/$tgz"
これらすべては、コマンドが次のようになると仮定します。シェル注文する。 Perlスクリプトについて言及しましたが、Perlは独自の参照レイヤーを追加するので、作成する内容は、文字列がPerlスクリプトに挿入される方法によって異なります。$input_path/$tgz
文字列はシェルスクリプトに挿入されるため、文字列はファイル名ではなくシェルフラグメントに解析されるため、使用は間違いなく問題があります。
シェルコマンドが二重引用符またはバックティックの間にある場合は、バックスラッシュを2倍にする必要があります。それでもスラッシュが誤ってソートされるという問題があります。 Perlで書かれた1つの方法は次のとおりです。
my $quoted_file_name = quotemeta("$input_path/$tgz");
system("pax -r -z -s '!.*/directory/!!p' -f $quoted_file_name");
を使用している場合は、system
中間シェルを呼び出さないために引用の問題を回避するには、リスト形式を使用する必要があります。
system('pax', '-r', '-z', '-s', '!.*/directory/!!p', '-f', "$input_path/$tgz");