2

curl を使用してプレーンテキスト ファイルを取得し、それを変数に割り当てる単純なスクリプトがあります。後でそれをエコーし​​、いくつかの行をgrepして一時ファイルに入れます(実際にはそれらを配列に入れたいです)。次に、それらを繰り返し処理して何かを行います。Mac OS X の 1 台のマシンで実行しましたが、ほとんど動作します。ただし、次のいずれかがランダムに発生します。

  • curl の出力は 1 行として扱われるため、echo/grep の段階で問題が発生します。
  • echo と for ループを実行すると、tmp ファイル全体が単一行として扱われるため (「読み取り行」を使用してこれを軽減したようです)、再び壊れます。

改行が一貫して確実に処理されるようにする方法はありますか? 常に同じである限り、私は気にしません。必要に応じて、1 行の curl 出力から結果を sed することもできます。

更新:別の場所から。マシンにログオンし、いくつかのことを行い、スクリプトが機能しないことに気付きました。いくつかのコマンド (結果、要約、以下) を実行してテストし、ログオフし、再度ログオンし、動作が変更されました (期待されるものに戻りました)。forループ出力の違いに注意してください...同じコマンドが(私が知っている限り)まったく同じenvで、改行が異なる場合のcurl出力でも同じことが起こります。私がやりたいことは、すべてのスクリプトの最初に何らかのコマンドを実行して、動作が決して変わらないことを 100% 確実にすることです。

[root@ip-xxx-xxx-xxx-xxx ~]# cat example.txt 
ip-xxx-xxx-xxx-xxx.ec2.internal
ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# for f in `cat example.txt`; do echo "line $f"; done
line ip-xxx-xxx-xxx-xxx.ec2.internal
ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# while read f; do echo "line $f"; done < "example.txt"
line ip-xxx-xxx-xxx-xxx.ec2.internal
line ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# logout
Connection to ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com closed.
reznor-mbp:trunk2 sergey$ ssh -i ... "root@..."
Last login: ...
[root@ip-xxx-xxx-xxx-xxx ~]# for f in `cat example.txt`; do echo "line $f"; done
line ip-xxx-xxx-xxx-xxx.ec2.internal
line ip-xxx-xxx-xxx-xxx.ec2.internal
4

3 に答える 3

4

最初: for で行を読まないでください。while readループでそれらを読み取ります:

while read -r; do
  echo "line $REPLY"
done <example.txt

問題for f in $(cat example.txt)は、ループに入る前に cat 操作の出力が文字列分割とグロブ展開を経て、動作が多くの変数 (IFSシェル設定の内容、現在のディレクトリ内のファイル [潜在的にグロブ-拡張名が存在する]、グロブの解釈方法に影響を与えるさまざまなシェルオプションなど)。while readアプローチは一貫して動作します。

2番目-同じ理由で常に展開を引用します。"$line"文字列分割とグロブ展開を回避します(再び、上記の設定と変数を無意味にします)が、裸で$lineはそれらが発生します。

最後に、上記の例では default 変数を使用しています。これは、これらの条件下での読み取り時REPLYに、シェルが空白文字 (つまり、 で見つかった文字) を削除しないためです。$IFSこれは通常は不要です (また、 のように IFS を明示的にクリアすることで同じ効果が得られますwhile IFS= read -r line; do ...) が、目標は再現可能であるため、適切に行っています。:)

これらのプラクティスに従うと、POSIX sh に準拠したすべてのシェル間で一貫した動作が見られます。(POSIX sh に準拠していない唯一の主要なシェル -- 標準で義務付けられた動作が不当であると見なされる場所でデフォルトで互換性を壊す -- は zsh です)。

于 2013-04-02T01:44:14.887 に答える
0

あなたは言及しechoます。あなたは書きますか

echo $multiLineVar

また

echo "$multiLineVar"

最初のケースでは、シェルは埋め込まれた改行を単語を区切る空白として扱うため、単語が表示されるechoことはありません。

于 2013-03-21T18:38:45.823 に答える
0

簡単な方法は、以下のように while ループを使用することです

filename=/path/to/file/file.txt
while read variablename

do echo "$variablename" done < "filename" \n まで行全体を読み取ります。

于 2014-06-26T12:45:59.010 に答える