web-dev-qa-db-ja.com

Linux:出力ファイルが一致するファイルのバッチでコマンドを実行します

簡単なタスク:ファイルのディレクトリと、1つのファイルを入力として受け取り、1つのファイルを出力として生成するコマンドが与えられた場合、ディレクトリ内のすべてのファイルを一度に処理し、対応する一致する名前(新しい拡張子)で出力したいと思います。

したがって、コマンドが通常次のようになる場合:

convert -input sourceFile.ext -output destFile.out

でフォルダを処理したい

file1.ext, file2.ext, etc.

同じディレクトリにファイルを作成します

file1.out, file2.out, etc.

Bashスクリプトを書かずにターミナルでこれを行う方法はありますか?私はスクリプトにあまり詳しくないので、簡単な解決策をいただければ幸いです。

4
donnyton

basenameを使用しない場合:

for file in *.ext; do convert -input "$file" -output "${file/%ext/out}"; done

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion を参照してください。

10
glenn jackman

findコマンドを調べます

必ず入力ディレクトリにcdしてください。

cd input_directory
find . -iname "*.ext" -exec convert -input {} -output {}.out \;

これにより、入力ファイルの名前に.outが追加されます。あなたの述べた出力ファイルを取得する私はまだ理解していません。

物事を変える-execを実行する前に、findが何をするかを試すことは常に賢明です。

cd input_directory    
find  .  -iname "*.ext"  -type f  -exec ls -l {} \;

一種の「ドライラン」を行います。

  • -exec実行するコマンド
  • {}どのファイルが見つかりましたか。一つずつ
  • \;はこれを使用して-execを終了する必要があります

私の限られた実験は、引用する必要がないことを示しています{}

$ find . -type f -exec ls -bl {} \;  
-rw-r--r--. 1 me me 0 Oct 20 19:03 ./a\ b\ c.txt  
-rw-r--r--. 1 me me 0 Oct 20 19:03 ./abc.txt  

$ ls -bl
total 0
-rw-r--r--. 1 me 0 Oct 20 19:03 a\ b\ c.txt
-rw-r--r--. 1 me 0 Oct 20 19:03 abc.txt
me ~/a $`

覚えにくいbashコマンドすべてへのヒントを含むテキストファイルhelp.txtがあります。ファイルを印刷するための簡単なスクリプトに関連付けています..、h

これが私の検索コマンドのリストです:

# searches for all files on the system for the string you fill in between the ""
Sudo find  /  -type f -exec grep -il "" {} \;
# search for all files starting with python.
find / -iname 'python*'
# search for the file type .jpeg and sort the list by date
find  ~  -iname "*.jpeg" -type f  -exec ls -l  {} \; 2>/dev/null | sort -r -k 8,8 -k 6,7M
# so I can remember the or syntax. 
find  ~  \( -iname "*.jpeg" -o -iname "*.png"  \) -type f  -exec ls -l  {} \;
5
historystamp

これを試してください(すべて1行です):

_find /path/to/folder -maxdepth 1 -iname \*.ext -exec sh -c 'convert -input "{}" -output "/path/to/folder/$(basename "{}" .ext).out"' \;
_

内訳は次のとおりです。

_find /path/to/folder -maxdepth 1 -iname \*.ext
_

_.ext_で_/path/to/folder_で終わるすべてのファイルを検索しますが、サブフォルダーでは検索しません。 _-exec_部分は、findコマンドが検出した各ファイルをどのように処理するかを指示します。次に、_{}_が出現するたびにファイルに置き換えられます。パターンは

_find /path/to/folder -iname \*.ext -exec echo "found this file: {}" \;
_

私が言ったように、_{}_は見つかったファイルの名前に展開されます。 _\;_は、_-exec_パラメーターの終わりを示します。この場合、_sh -c_が使用されます。そうしないと、コマンド$(basename {} .ext)がシェルによって時期尚早に展開されるためです。そのため、拡張を防ぐために一重引用符で囲み、シェルの別のインスタンスに渡します。 _{}_はfindによって展開され、コマンドの残りの部分はそのままshに渡されます。コマンド

_$(basename "filename.ext" .ext).out
_

_"filename.ext"_から拡張子を削除し、_.out_拡張子を追加します。

[〜#〜]編集[〜#〜]

そのコマンドがいかに近づきにくいかを理解しました。これがその最も必要最低限​​のバージョンです。

_find . -name \*.ext -exec sh -c 'convert -input {} -output $(basename {} .ext).out' \;
_

今回はスクロールせずにほぼ収まります。 :)

4
nispio

「bashスクリプトを書く」とはどういう意味かによります。以下はbashスクリプトですが、必要に応じてターミナルに入力するだけです。ファイルに入れる必要はありません。

cd_directory_where_the files_are_
_for x in *.ext_
do
        convert -input "$x" -output $(basename "$x" .ext).out
done

これは、cd先のディレクトリ内の_*.ext_ファイルに対してのみ機能します。サブディレクトリも検索する場合は、findが最適なソリューションです。例: nispioの回答 を使用しますが、_-maxdepth 1_は省略します。


編集:nispioの答えに対するHennesのコメントはここにも当てはまります。あなたは言えた

_for x in /path/to/folder/*.ext_
do
        convert -input "$x" -output $(basename "$x" .ext).out
done

2
Scott