web-dev-qa-db-ja.com

Bash:ファイルを1行ずつ読み取り、各セグメントを他のプログラムへのパラメーターとして処理します

汚い仕事がいくつかあるので、Bashスクリプトが良い選択のようです。私はBashを初めて使用しますが、この経験から不満を感じています。

ファイルmapfiles.txtは、次のような行で構成されています。各行には、空白で区切られた4つのセグメントがあります。各セグメントは、外部プログラム名「prog」への入力パラメーターを表します。たとえば、「cm19_1.png」はファイル名、「0001」はインデックス、「121422481」は経度、および「31035995」は緯度

ファイル:mapfiles.txt

cm19_1.png 0001 121422481 31035995
cm19_2.png 0002 121423224 31035995
cm19_3.png 0003 121423967 31035995
…

各行に対して同様のコマンドを実行したい。以下に示すように、progの入力パラメーターの順序はわずかに異なります。そのため、繰り返し作業を処理するbashスクリプトを作成するのは理にかなっています。

[Usage] prog <index> <longitude> <latitude> <filename>
example: prog 0001 121422481 31035995 cm19_1.png

通常、bashスクリプトは次のように動作します。

  1. Mapfiles.txtから1行読み取ります
  2. セグメントを分割する
  3. 正しいパラメーターの順序でプログラムを呼び出します

ここにrun.shがあります。

#!/bin/sh

input=mapfiles.txt
cmd=prog

while read line
do
        file=$(echo $line | cut -d' ' -f1)
        key=$(echo $line | cut -d' ' -f2)
        log=$(echo $line | cut -d' ' -f3)
        lat=$(echo $line | cut -d' ' -f4)
        echo $cmd $key $log $lat $file
done < "$input"

私が期待したのは

prog 0001 121422481 31035995 cm19_1.png
prog 0002 121423224 31035995 cm19_2.png
prog 0003 121423967 31035995 cm19_3.png
… 

私が得た実際の結果は

 cm19_1.png21422481 31035995
 cm19_2.png21423224 31035995
 cm19_3.png21423967 31035995

私を混乱させた問題

  1. 「prog」はどこにありますか?
  2. ホワイトスペースはどこにありますか?
  3. パラメーターの順序の何が問題になっていますか?

うーん...このスクリプトをvimを使用してMacで作成し、Scientific LinuxボックスとGentooボックスにコピーしました。これらの3人は同じばかげた出力を取得します。

35
Jianwen W.

これを非常に単純化できます:

while read file key log lat
do
  echo "$cmd" "$key" "$log" "$lat" "$file"
done < "$input"
48
Mat

GNU Parallelを使用すると、1行で実行できます+無料で並列に実行できます。

cat mapfile.txt | parallel --colsep '\s' prog {2} {3} {4} {1}

詳細については、紹介ビデオをご覧ください: http://www.youtube.com/watch?v=OpaiGYxkSuQ

9
Ole Tange

progは、$cmdはエクスポートされません。/bin/shのバージョンは、別のシェルでwhileステートメントを実行する場合があります。これは当てはまらないはずであり、bashをインストールした場合は当てはまりませんが、この部門ではおもしろい振る舞いをするかもしれません。

[〜#〜] upd [〜#〜]同じ結果が得られる複数のボックスがあることがわかります。これにより、サブシェル理論が成り立たなくなります。おそらく、スクリプトやソースファイルに面白い文字が含まれている可能性があります。

スクリプトとソースファイルをコピーしてgentooボックスに貼り付けたところ、期待どおりの結果が得られました。おそらく同じことをして、ファイルを元のファイルと比較する必要があります。

2
n.m.