テキストファイルの各行をコマンド引数に解析する方法は?

テキストファイルの各行をコマンド引数に解析する方法は?

.txt私はファイル名を引数として使用してファイルを1行ずつ読み込み、各行をコマンドに渡すスクリプトを作成しています。たとえば、command --option "LINE 1"thencommand --option "LINE 2"などを実行します。コマンドの出力は他のファイルに書き込まれます。どうすればいいですか?どこから始めるべきかわかりません。

答え1

別のオプションはですxargs

GNUの使用xargs:

xargs -a file -I{} -d'\n' command --option {} other args

{}テキスト行のプレースホルダーです。

他には一般的にはありxargsませんが、一部にはNULで区切られた入力があります。これにより、次のことができます。-a-d-0

< file tr '\n' '\0' | xargs -0 -I{} command --option {} other args

Unix互換システム(-IPOSIXではオプション、UNIX互換システムのみ)では入力を前処理する必要があります。引用する予想される形式の行xargs:

< file sed 's/"/"\\""/g;s/.*/"&"/' |
  xargs -E '' -I{} command --option {} other args

ただし、一部のxargs実装では、引数の最大サイズに対する制限は非常に低いです(たとえば、Unix仕様で許可されている最小値であるSolarisでは255)。

答え2

while readループを使用してください。

: > another_file  ## Truncate file.

while IFS= read -r line; do
    command --option "$line" >> another_file
done < file

別の方法は、出力をチャンクにリダイレクトすることです。

while IFS= read -r line; do
    command --option "$line"
done < file > another_file

最後にファイルを開きます。

exec 4> another_file

while IFS= read -r line; do
    command --option "$line" >&4
    echo xyz  ## Another optional command that sends output to stdout.
done < file

コマンドの1つが入力を読み取る場合は、コマンドが入力を食べないように、入力に別のfdを使用することをお勧めします(これは代わりにポータブル代替が使用されると仮定kshします)。zshbash-u 3<&3

while IFS= read -ru 3 line; do
    ...
done 3< file

最終的にパラメーターを受け入れるには、次のようにします。

#!/bin/bash

file=$1
another_file=$2

exec 4> "$another_file"

while IFS= read -ru 3 line; do
    command --option "$line" >&4
done 3< "$file"

どちらを次のように実行できますか?

bash script.sh file another_file

追加の考え。でbash使用readarray:

readarray -t lines < "$file"

for line in "${lines[@]}"; do
    ...
done

注:IFS=行の値から先行スペースと末尾のスペースを削除しても問題ない場合は、この項目を省略できます。

答え3

この質問に正確に答えてください。

#!/bin/bash

# xargs -n param sets how many lines from the input to send to the command

# Call command once per line
[[ -f $1 ]] && cat $1 | xargs -n1 command --option

# Call command with 2 lines as args, such as an openvpn password file
# [[ -f $1 ]] && cat $1 | xargs -n2 command --option

# Call command with all lines as args
# [[ -f $1 ]] && cat $1 | xargs command --option

答え4

    sed "s/'/'\\\\''/g;s/.*/\$* '&'/" <<\FILE |\
    sh -s -- command echo --option
all of the{&}se li$n\es 'are safely shell
quoted and handed to command as its last argument
following --option, and, here, before that echo
FILE

出力

--option all of the{&}se li$n\es 'are safely shell
--option quoted and handed to command as its last argument
--option following --option, and, here, before that echo

関連情報