2

前文:それで、私はたくさんのファイルに対して変換ツールを実行する必要があるプロジェクトを持っています。変換には複数の手順があり、時間がかかる場合があります。これらのファイルは必ずしも同じディレクトリにあるとは限らないため、変換するファイル名を使用してテキストファイルを作成しました。

<filenames.txt>

/home/me/Documents/file1.txt
/home/me/Documents/file2.txt
/home/me/Documents/file3.txt

問題:次に、これらのファイルに対して実行するbashスクリプトがあり、変換手順を実行します。ただし、フェーズとファイル名をエコーし​​ようとします。この場合、echoは、エコーされたテキストをファイル名の中央に貼り付けます。

<script.sh>

cat filenames.txt | while read some_file
do
    echo
    echo "Begin FORMAT_A to FORMAT_B conversion..."
    echo "FORMAT_A Filename:"
    echo $some_file
    formatb_dir= dirname $some_file | tr '\n' "/"
    formatb_file= basename $some_file ".xml" | tr '\n' "_"
    formatb=$formatb_dir$formatb_file"form_b.xml\n"

    echo "FORMAT_B Filename:"
    echo $formatb
done

次のような出力を生成します。

Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file1.txt
/home/me/Documents/file1.txt_FORMAT_B Filename:
form_b.xml


Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file2.txt
/home/me/Documents/file2.txt_FORMAT_B Filename:
form_b.xml


Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file3.txt
/home/me/Documents/file3.txt_FORMAT_B Filename:
form_b.xml

エコーされたテキストである「FORMAT_BFilename」は、追加されたテキスト「form_b.xml」の前に表示されています。

dirname、basename、echo、trのマニュアルページを調べましたが、表示されているものを引き起こすと思われるものは見つかりませんでした。Googleで調べてみましたが、正しい質問をしているのかわかりません(「変数の前にbashエコーテキスト」?)。

質問:エコーがエコーされたテキストを変数の中央に配置するのはなぜですか?

(関連する可能性のある質問:「私は自分がしていることを完全に間違った方法で行っているのですか?」)

編集:変数について理解していないことやコマンドからの出力を取得する方法を説明してくれたので、forteaの回答を受け入れました。そうは言っても、dogbaneとJonathan Lefflerは、私がやっていることを行うためのより良い方法を示しました。

4

3 に答える 3

2

問題は変数の宣言にあります:

formatb_dir= dirname $some_file | tr '\n' "/"
formatb_file= basename $some_file ".xml" | tr '\n' "_"
formatb=$formatb_dir$formatb_file"form_b.xml\n"

新しい行を試してください: echo $formatb_dir: 「=」の後に空白があるため、何も含まれていません。次に、bash が読み取りdirname $somefile |tr '\n' "/"、このコマンドを実行します。formatb_file を作成するときも同じですが、今回はコマンドが basename です。(これは、「FORMAT_B Filename:」の前に表示されるものです)。次に、formatb は正しく作成されますが、$formatb_dir と $formatb_file は空であるため、$formatb には"form_b.xml\n". 次に、「FORMAT_B ファイル名:」をエコーし​​ます。次に、「form_b.xml」を出力する $formatb をエコーし​​ます。

したがって、次のようなものを使用する必要があります。

formatb_dir=$(dirname $some_file | tr '\n' "/")
formatb_file=$(basename $some_file ".xml" | tr '\n' "_")
formatb=$formatb_dir$formatb_file"form_b.xml\n"

ここを読む

于 2012-11-01T11:29:51.467 に答える
2

問題は、出力をキャプチャするのではなく、環境を奇妙な方法で設定して、のdirnameようなコマンドを実行していることです。basenameつまり、次を実行した場合:

env_var=some_value commandname arg1 arg2

プログラムcommandnameは、環境変数$env_varが に設定された状態で実行されますsome_value(このコマンドのみ)。あなたのコードでは、次のように書きました。

formatb_dir= dirname $some_file | tr '\n' "/"

これは、私が示した例と同形です。dirname環境変数formatb_dirを空の文字列に設定してコマンドを実行し(これをdirname完全に無視します)、標準出力へdirnametr出力と の出力を送信します。tr

  • シェルの割り当ての前後にスペースはありません
  • $(...)出力をキャプチャするために使用します。
  • ファイル名に改行を埋め込まないでください。それは人生を地獄にするでしょう!

dirname出力の最後の改行をスラッシュにマッピングしたり、出力の最後の改行をアンダースコアにマッピングしたりすることは気にしませんbasename。生成された名前にスラッシュとアンダースコアを追加できます。

修理済み:

cat filenames.txt |
while read some_file
do
    echo
    echo "Begin FORMAT_A to FORMAT_B conversion..."
    echo "FORMAT_A Filename:"
    echo $some_file
    formatb_dir=$(dirname "$some_file")
    formatb_file=$(basename "$some_file" ".xml")
    formatb="${formatb_dir}/${formatb_file}_form_b.xml"
    echo "FORMAT_B Filename:"
    echo $formatb
done

の割り当ては、一貫性を保つために 2 回formatb使用します。${varname}ブレースは展開の周りにのみ必要${formatb_file}です。

于 2012-11-01T11:44:44.957 に答える
1

それは、キャラクターを使用trおよび削除しているためです。\n

を使用する代わりにtr、単純に文字列を連結してみませんか?

formatb_dir="$(dirname ${some_file})"
formatb_file="$(basename ${some_file})"
formatb="${formatb_dir}/${formatb_file}_form_b.xml"
echo "FORMAT_B Filename: $formatb"
于 2012-11-01T11:33:33.620 に答える