ファイルのパラメータ(ファイル名)を使用してコマンドを複数回実行しますか?

ファイルのパラメータ(ファイル名)を使用してコマンドを複数回実行しますか?

長いファイル名のリスト(フルパスを含む)を含むファイルがあります。また、このリストのプログラムとファイル名を引数として使用して複数回実行したいプログラムもあります。残念ながら、私が実行したいプログラムはホームブリッジスクリプトなので、唯一のオプションは次のとおりです。一つファイル名を入力すると許可されません。標準入力(ファイル名のリストなど) - したがって、パイピングや入力リダイレクトはできません。

私に必要なのは実行されるコマンドですその他コマンド(マイスクリプト)、ファイルの行をパラメータとして使用します。

find-action -exec...(find . -name "*.txt" -exec command \;)に似ています。私の考えでは、私は実際にできるここで使用されていますが、find入力ファイルを並べ替えたいのですが...

だから私に必要なのはこれです:

for_each_command1 -f ファイルリスト -c './my_command{}'
for_each_command2 -f ファイルリスト-exec ./my_command{}\;
for_each_command3 -c './my_command {}'

この種のタスクを処理する一般的な方法はsed- 残念ながらオーバーヘッドが多く、あまり良くありません(しかしする働く...):

$wc -l ファイル一覧 第232話 $ for (( i=1;はい > ./my_command "`sed -n "${i}p"ファイルのリスト`" >完了

それでは、これらのことを処理できる組み込みコマンドまたはシェルはありますか?

答え1

便利で、xargs -Iお客様の要件を完全に満たしています。

$ xargs <my_file_list.txt -I filename ./my_command "filename"
-I replace-str
    Replace occurrences of replace-str in the initial-arguments with names read
    from standard input.
    Also, unquoted blanks do not terminate input items;
    instead the separator is the newline character.
    Implies -x and -L 1.

つまり、改行で区切られた入力行のみを取り、それを単一の引数として使用してコマンドを呼び出します。改行文字以外のものは区切り文字と見なされないため、スペースやその他の特殊文字は問題ありません。

ファイル名に改行を許可するには、ワイルドカードの回答に応じてNULLターミネーターもファイルで機能します。

答え2

あなたのファイルのリストが「filelist.txt」というファイルに保存され、各ファイル名が1行に保存されているとします。その後、各行を次のパラメータとして使用してスクリプトを呼び出すことができます。

while read name; do
  ./yoursrcipt.sh "$name"
done <filelist.txt

答え3

私は通常ポータブル(POSIX)ソリューションを好むが、シンプルで明白ですこれに対する答えは、GNU拡張を使って人生をより簡単にすることです。

find . -type f -name '*.txt' -print0 | sort -z | xargs -n1 -r0 ./mycommand

これは、ファイル名間の区切り文字としてヌルバイトを使用します。これは、ファイル名に次のものが含まれる可能性があるため重要です。どの改行を含む文字。

(スラッシュはパスコンポーネントの区切り文字であるため保存されますが、この場合はファイル区切り文字として使用できないため重要ではありません。)

答え4

$ cat baard.in
/path/to/some space file
/some   tabbed/some     tabbed  file
/path to/genericfile
/path/to/regular.file
/path/to/exciting!/file!
/path/to/(parenthetical)/file.txt

$ cat my_command
#!/bin/sh
printf "my_command: %s\n" "$1"

awkはすでに行を解析しているので、それを使用して各レコードのコマンドを呼び出すことができ、引数を引用するときに注意する必要があります。

$ awk '{system("./my_command '\''" $0 "'\''");}' < baard.in
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt

ただし、入力に一重引用符が含まれていると、awkコマンドは失敗します。たとえば、次のようになります。

/books/Hitchhiker's Guide to the Galaxy.epub

bashが利用可能な場合は、次のものを使用できます。

$ readarray -t paths < baard.in
$ for((i=0;i < ${#paths[*]}; i++)); do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub

またはksh93で(ザイルズの答えはここにありますreadarrayを手動で実装する場合):

$ IFS=$'\n'; set -f
$ paths=( $(< baard.in) )
$ unset IFS; set +f
$ for((i=0;i < ${#paths[*]}; i++)) do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub

関連情報