web-dev-qa-db-ja.com

ファイルの行をコマンドの引数として使用するにはどうすればよいですか?

たとえば、foo.txt引数がN引数で指定されているとします

arg1
arg2
...
argN

これをコマンドmy_commandに渡す必要があります

ファイルの行をコマンドの引数として使用するにはどうすればよいですか?

125
Yoo

シェルが(特に)bashの場合、$(cat afile)のショートカットは$(< afile)なので、次のように記述します。

mycommand "$(< file.txt)"

「コマンドの置換」セクションのbashのマニュアルページに記載されています。

あるいは、コマンドを標準入力から読み込むようにします:mycommand < file.txt

194
glenn jackman

すでに述べたように、バックティックまたは$(cat filename)を使用できます。

言及されなかったこと、そして私が注意することが重要だと思うことは、シェルがそのファイルの内容を空白に従って分割し、コマンドに見つけた各「単語」を引数として与えることを覚えておく必要があることです。また、コマンドライン引数を引用符で囲み、空白、エスケープシーケンスなどを含めることができる場合がありますが、ファイルからの読み取りでは同じことはできません。たとえば、ファイルに次が含まれている場合:

a "b c" d

取得する引数は次のとおりです。

a
"b
c"
d

各行を引数として取得する場合は、while/read/do構造を使用します。

while read i ; do command_name $i ; done < filename
35
Will

バックティックを使用してそれを行います。

echo World > file.txt
echo Hello `cat file.txt`
15
Tommy Lacroix
command `< file`

は、ファイルの内容を標準入力のコマンドに渡しますが、改行を削除します。つまり、各行を個別に繰り返すことはできません。そのために、「for」ループを使用してスクリプトを作成できます。

for i in `cat input_file`; do some_command $i; done
14
Wesley Rice

可能なすべてのコマンドライン引数(スペースを含む値、改行を含む値、リテラル引用符を含む値、印刷できない値、グロブ文字を含む値など)で機能する堅牢な方法でこれを実行したい場合は、少し取得しますもっと面白い。


引数の配列を指定してファイルに書き込むには:

printf '%s\0' "${arguments[@]}" >file

...必要に応じて、"argument one""argument two"などに置き換えます。


そのファイルから読み取り、その内容を使用するには(bash、ksh93、または配列を持つ別の最近のシェルで):

declare -a args=()
while IFS='' read -r -d '' item; do
  args+=( "$item" )
done <file
run_your_command "${args[@]}"

そのファイルから読み取り、その内容を使用するには(配列のないシェルで。これはローカルのコマンドライン引数リストを上書きするため、関数の引数を上書きするのではなく、関数の内部で行うのが最適です。グローバルリスト):

set --
while IFS='' read -r -d '' item; do
  set -- "$@" "$item"
done <file
run_your_command "$@"

-d(異なる行末デリミタの使用を許可する)は非POSIX拡張機能であり、配列のないシェルもサポートしない可能性があることに注意してください。その場合、非シェル言語を使用して、NULで区切られたコンテンツをeval- safeフォームに変換する必要がある場合があります。

quoted_list() {
  ## Works with either Python 2.x or 3.x
  python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
  '
}

eval "set -- $(quoted_list <file)"
run_your_command "$@"
7
Charles Duffy

ファイルの内容を引数としてコマンドに渡す方法は次のとおりです。

./foo --bar "$(cat ./bar.txt)"
6
chovy

私のbashシェルでは、以下が魅力のように機能しました。

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

input_fileは

arg1
arg2
arg3

明らかなように、これによりinput_fileの各行で複数のコマンドを実行できます。これは、私が学んだ素敵なちょっとしたトリックです here

2
honkaboy