入力テキストファイルを1行ずつ読み、2つの文字列をテキストファイルの各行の変数として渡すために、while readループ行を設定しようとしています。
while IFS= read -r line
do
# Read and pass two path strings as variables.
read path1 path2
echo "$path1"
echo "$path2"
done < "$1"
read path1 path2
現在の行の各文字列に変数を割り当てる前に、テキストファイルの次の行を処理するようです。
次の行に移動する前に、各行に文字列を変数として渡すことはできますか?
答え1
read
ループ本体内の2番目の項目はここでは正しくありません。read
whileループの一部として、実際には最初の呼び出しより1行前です。したがって、あなたの要件に応じて、これらの変数を最初の変数の一部として読みます。read
while read -r path1 path2; do
echo "$path1"
echo "$path2"
done < "$1"
ここに示すように、IFS=
フィールド区切り文字をリセットすると行全体が選択されるため、両方の変数を読み取るときに設定も正しくありません。 2つの変数を読み取ると、デフォルト値(スペース、タブ、改行などのスペース文字)を使用して、スペースで区切られたリストに各行の値が格納されます。このようにして、行を区切るn個の列を持つことができ、n個の変数を使用して読み取ることができます。
これで、これらの変数で値を使用でき、必要に応じて他のコマンドに渡すことができます。
サンプル入力ファイルでこれがどのように機能するかを見てみましょう。
foo bar
foo1 bar1
foo2 bar2
-x
set を使用してデバッグモードで最初のスクリプトを実行します。
$ bash -x script.sh
+ read -r path1 path2
+ echo 1
1
+ echo 2
2
+ read -r path1 path2
+ echo 3
3
+ echo 4
4
+ read -r path1 path2
+ echo abc
abc
+ echo def
def
+ read -r path1 path2
答え2
ラインをそのまま維持したい場合そしてそれから値を抽出するには、次を使用できます。ここにある文字列:
while IFS= read -r line; do
read -r path1 path1 <<< "$line"
echo "$line"
echo "$path1:$path2"
done < file
実際、すべてのシェルがhere-stringをサポートしているわけではありません。ただし、このドキュメントはすべてのPOSIXタイプシェルでサポートされています。
while IFS= read -r line; do
read -r path1 path1 << _LINE_
$line
_LINE_
echo "$line"
echo "$path1:$path2"
done < file
答え3
ファイルをfor
ループにリダイレクトすると、ループ全体で標準入力のすべての読み取りが同じファイルから読み取られます。つまり、read
ループ内の2つのコマンドは、最初の引数としてスクリプトに渡したファイルから代替行を読み取ります。
path1
データをどこから取得したいのか少し不明ですpath2
。ファイルからそれを読むには、ループヘッダーで実行します。
while read -r path1 path2; do
printf 'path1 = "%s"\n' "$path1"
printf 'path2 = "%s"\n' "$path2"
done <"somefile"
この回答の残りの部分では、ファイルから何かを読み、次にループの端末で何かを読み取ろうとします。
read
ループ本体を端末から読み取るには:
exec 3<"somefile"
while IFS= read -r words <&3; do
read -r word1 word2 junk
printf 'Got words = "%s"\n' "$words"
printf 'Got word1 = "%s"\n' "$word1"
printf 'Got word2 = "%s"\n' "$word2"
done
これにより、最初の入力はread
ファイルから出力されsomefile
、2番目の標準入力ストリームはread
端末(またはスクリプトの標準入力ストリームが出てくる場所)から読み取られます。