2016-04-24 16 views
3

は私が含まれていitemlist.txtという名前のテキストファイルを操作しようとしています:私は、コードのさまざまなバリエーションを試してみた複数のループを使用して出力を複数の変数に格納するにはどうすればよいですか?

http://example.com/item-a 
http://example.com/item-b 
http://example.com/item-c 
http://example.com/item-d 
http://example.com/item-e 

。いくつかは、項目だけを返しますが、URLは返しません。私は$urlを正しく割り当てる方法を理解できません。これは、私が望む出力を達成するために最も近い点です。

#!/bin/bash 

while read url; do 
for item in $(sed "s/http:\/\/example.com\///g"); do 
echo $item $url; done 
done < itemlist.txt 

所望の出力は次のようになります。

item-a http://example.com/item-a 
item-b http://example.com/item-b 
item-c http://example.com/item-c 
item-d http://example.com/item-d 
item-e http://example.com/item-e 

しかし、その代わりに、私は取得しています:

item-b http://example.com/item-a 
item-c http://example.com/item-a 
item-d http://example.com/item-a 
item-e http://example.com/item-a 

誰かがこれを正しく行う方法にいくつかの光を当てることができますか?

答えて

7

sedを使用しないでください。 URLの最後の/までのすべてを削除するには、パラメータ拡張を使用してください。

while IFS= read -r url; do 
    item=${url##*/} 
    echo "$item $url" 
done < itemlist.txt 

(あなたの問題は、方法によって、sedread両方がitemlist.txtから読んでいるということです。。。readは、最初の行を取得し、sedは残りを消費あなたのwhileループ終了最初の反復の後)

+1

++説明のため;全体として、私はまだシェルループ上で単一のツール呼び出しをお勧めします。 – mklement0

+1

2番目の考えでは、タイトルはシェル変数_の結果が必須であることを示唆していますが、これは結果が終わるまでの単なる手段であるかどうかは不明です。いずれの方法でも_sis variables_に各行の結果を格納する必要がある場合は_this_ answerを使用します。それが重要なのは標準出力だけであれば 'awk'解決策を考えてみてください。 – mklement0

+1

合意。シェルにはいくつかの初歩的なデータ処理能力がありますが、一般的には、他のプログラムを実行するシェルの主たる目的をサポートするためにのみ使用してください。独自のデータ処理は 'awk'のようなより適切な言語で行うべきです。 – chepner

3

この回答は、結果をstdoutに出力することを前提としています。これとは対照的に、各入力行のシェル変数に結果コンポーネントを格納する必要がある場合は、chepner's helpful answerを参照してください。

awkおそらくここで使用する最適なツールです。

awk -F/ '{ print $NF, $0 }' itemlist.txt 
  • -F/分割/
  • $NFによってフィールドに、各入力行が
  • 各入力行に最後フィールドです$0は完全な入力行です。
  • printは、デフォルトでは(組み込み変数OFSに基づいて、それぞれOFSに変更された)1つのスペースで区切られた引数を表示します。
2

まあ、awkはおそらくmklement0's answerで示された最良のツールです。しかし、別のオプションを持つことに害はありません。

sed-rオプションがない場合は、すべての括弧をエスケープしてください。私はデリミタとして#を使用しました。キャプチャグループの一部として使用される/をエスケープすることで、従来のものを使用できます。

ロジックはかなりシンプルです。キャプチャグループの最後の部分まで貪欲にすべてをキャプチャします。最後の部分を別のキャプチャグループでキャプチャし、目的の出力に合わせて使用​​します。

$ sed -r 's#(.*/)(.*)$#\2 \1\2#' file 
item-a http://example.com/item-a 
item-b http://example.com/item-b 
item-c http://example.com/item-c 
item-d http://example.com/item-d 
item-e http://example.com/item-e 
+0

++; '-r'の代わりに' -E'を使うと、OS Xでも動作します( '-E'は_GNU_' sed'の 'man'ページには書かれていませんが、エイリアスとして動作します'-r'の) – mklement0

+1

少し錆びているので、しばしばそれに答えない。 ';)' –

関連する問題