複数のファイルに対してコマンドを実行し、各出力に一意の名前を付けます。

複数のファイルに対してコマンドを実行し、各出力に一意の名前を付けます。

次のように、フォルダ内のすべてのファイルに対してスクリプトを実行したいと思います。

sh script.sh *.fasta > output

しかし、各入力の出力が別々のファイルにあることを望みます。もしそうなら、コマンドを介して5つのファイルをインポートして「output」というファイルにすべて入れるのではなく、出力をファイル名にし、最後に「_output」などのサフィックスを追加する方法はありますか?

したがって、次の3つのファイルがある場合:

file1.fasta
file2.fasta
file3.fasta

次のコマンドを実行する方法はありますか?

sh script.sh *.fasta

そして、各入力に対して次のような新しいファイルを出力します。

file1_new.fasta
file2_new.fasta
file3_new.fasta

私は次のコマンドを試しました。

sh script.sh *.fasta > *_output.fasta

しかし、うまくいきません。興味のあるすべてのファイルをこのような変数に割り当てようとしました。まず、変数に割り当てると何とか出力名を変更できると思いました。

allthefiles= *.fasta

しかし、それも動作しません。この質問を何と呼ぶべきかわかりません。既に質問されたらすみません!コマンドを介して複数のファイルを実行し、各入力に新しい出力を提供する方法は?

答え1

for f in *.fasta; do 
    sh script.sh "$f" > "${f%.*}_output.fasta"; 
done

# ${f%.*} strips a shortest match of `.*` from the end of "$f"
# (= strips .fasta)

答え2

使用作る

というファイルを作成します。GNUmakefile内容は次のとおりです。

all: $(filter-out %_output.fasta,$(wildcard *.fasta))

%_output.fasta: %.fasta
↦./script.sh $< >[email protected]
↦mv [email protected] $@

すべてのファイルを再生成するには、.と入力しますmake。ボーナスとして、最後の出力ファイルが作成されてから入力ファイルが変更されていない場合はscript.sh再実行されません。積極的に修正しscript.shて出力ファイルを再生成するには、スクリプトが変更された後にファイルを再生成するようにscript.sh後ろに追加します。%.fasta

説明する:

  • 最初の行は、実行時に実行するアクションを指定しますmake all。なぜならこれが最初の行であるからです(最初の行ターゲット(makefileという用語で)make引数なしで実行すると、同じことが行われます。
  • 次のセクションでは、all:現在のディレクトリにファイル名のリストを作成し、.fasta名前を_output.fasta
  • 行は%_output.fasta: %.fasta次から始まります。ルール_output.fasta(で始まる名前を生成する方法について説明します。ターゲット)対応する.fastaファイル(a依存)。
  • 次のタブにインデントされた行は、ファイルを生成するために実行する必要があるコマンドです。
  • 最初の行は最初の依存関係()をファイル$<に変換します。.tmp
  • 2行目は.tmpファイル名をターゲットファイル($@)に変更します。この2段階のプロセスを実行する理由は、何らかの理由でビルドが中断されても無効なオブジェクトファイルが残らないためです。

注:Linuxを使用しているとします。それ以外の場合、make上記のコードを使用するには、システムのデフォルトコマンドの代わりにGNU makeをインストールして実行する必要があります。

出力ファイルに別の拡張子を使用すると、状況が少し簡単になります。

all: $(patsubst %.fasta,%.out,$(wildcard *.fasta))

.SUFFIX: .out .fasta
.fast.out:
↦./script.sh $< >[email protected]
↦mv [email protected] $@

all: foo.out bar.out最初の行を明示的なファイルリスト()に置き換えると、Makefileそのファイルを呼び出してmake

答え3

gnu 並列を使用して並列に実行できます。

parallel "sh script.sh {} > {}.out" ::: *

答え4

これは一行の解決策です

find ./ -name "*.fasta" -exec sh -c 'script.sh ${0} > ${0}.log' {} \;

つまり、目的のファイルを見つけて、そのファイルに対してスクリプトを実行します。使用目的は、sh -cリダイレクト文字を直接解釈することではありません。>

関連情報