web-dev-qa-db-ja.com

base64でエンコードされたファイル名のリストをデコードするにはどうすればよいですか?

{base64-encoded part here}_2015-11-12.pdfのパターンでbase64でエンコードされたファイル名のリストがあります。そのファイルのリストをデコードして、コマンドラインで改行で区切られた別のリストとして返します。これが私が今試していることです:

find . -name "*_*" -printf "%f\0" | sed 's/_....-..-..\.pdf//g' | xargs -0 -i echo "{}" | base64 -d

私がここでやっていることはだと思います。 。 。

  1. ファイルを検索し、ヌル文字で区切られたファイル名のみを出力します(つまり、「。/」プレフィックスを削除します)。
  2. sedを使用して、base64でエンコードされた部分のみを保持します(つまり、ファイル名の_2015-11-12.pdf部分を削除します)
  3. xargsを使用して、表面上は各ファイル名をエコーに渡します
  4. 次に、echoによって返された値をデコードします。

その結果、base64でデコードされたすべてのファイル名の大きな文字列になります。各名前はヌル文字で区切られ、文字列全体の後に改行が続きます。 desiredの結果は、それ自体が1行にある個々のデコードされたファイル名になります。

私はこれを修正するためにあらゆる種類のトリックを試しましたが、うまくいくものは何も見つかりませんでした。私は... | base64 -d | echo... | base64 -d && echoなどを試し、途中のさまざまなポイントに改行を挿入しようとしました。値が| base64 -dになるまでに、すべてが1つの文字列として一度に処理されるようです。ファイル名のモノリシックリストとしてではなく、各値をbase64 -dに一度に1つずつ送信する方法を見つけようとしています。

4
hourback

各ファイル名の後に改行のbase64エンコーディング(Cg==)を追加し、すべてをbase64 -dにパイプするだけです。

find . -name "*_*" -printf "%f\n" |
  sed -n 's/_....-..-..\.pdf$/Cg==/p' |
  base64 -d

あなたのアプローチでは、それは次のようなものでなければなりません:

find . -name "*_*" -printf "%f\0" |
  sed -zn 's/_....-..-..\.pdf$//p' |
  xargs -r0 sh -c '
    for i do
      echo "$i" | base64 -d
    done' sh

これらのパイプラインを作成するにはシェルが必要です。しかし、これはファイルごとにいくつかのコマンドを実行することを意味し、これは非常に非効率的です。

5

1つのトリックは、base64で\nをエンコードすることです...これはCg==になり、printfコマンドに追加できます。 '\'をファイル名に含めることはできません。結局、それを元に戻すことができます

find . -name "*_*" -printf "%f\0Cg==" | sed 's/_....-..-..\.pdf//g' | xargs -0 -i echo "{}" | base64 -d | sed 's/\\n/\n/g'

2
Varon