2016-09-25 18 views
1

CSVファイルをループしています。印刷、変更、印刷Bash変数

planet_85.287_27.665_51a5fb91、AcDbEntity:AcDbPolyline、{[名前] Purano バスパークThimi [タイプ]ルート[ルートファイルの各行は、このようなものを(それはのオープンストリートマップのデータ)フォーマットされ]マイクロバス[参考文献] 10} {[ID] 13.0 [SRID] 3857 [FieldsTableId]

これはフォーマット以下:

レイヤ、サブクラス、ExtendedEntity、線種、EntityHandle、テキスト

Nameの新しい列を追加したいとします。私は[名前]の前と[[の後ろ]の前にすべてを切り捨てて名前を見つけることができます。このコードは、名前のすべてを改行して改行したファイルを作成します(CSVとして開き、元のファイルにコピーして新しい列としてコピーします)。

cat /path/to/myfile.csv | while read line 
    do 
    if [[ ${line} == *"name"* ]] 
     then 
      printf "$(echo $line | LC_ALL=C sed 's/^.*name\]//g'| LC_ALL=C cut -f1 -d'[') \n" 
     else 
      printf "\n" 
    fi 
done >/path/to/newrow.csv 

このシステムは明らかに最適ではありません。最終的な行全体を印刷する方がはるかに優れています。しかし、私はこのprintf行を次のように置き換えます:

printf "$line,$(echo $line | LC_ALL=C sed 's/^.*name\]//g'| LC_ALL=C cut -f1 -d'[') \n" 

これは行であって名前ではありません。私は別の印刷ステートメントでそれらを印刷しようとしました、行を印刷して、名前をエコーし​​、変数に名前を保存してから印刷するなどの方法がありました。 b)CSV形式を破る新しい行に名前を表示する。

私は間違っていますか?最終的に新しい列として追加された名前で完全な元の行を印刷するにはどうすればよいですか?

注:私はMacBook Proの15" 網膜上のMacOSシエラのターミナルでこれを実行しています

+1

FYI - 'printf'を使用すると、置換は後続の引数にのみ指定する必要があり、書式文字列自体では使用しないでください。 –

+1

...行ごとに 'sed'と' cut'を実行するのは非常に、非常に非効率的です - 行単位で処理するつもりなら、[bash-native文字列操作](http://mywiki.wooledge.org/BashFAQ/100)を参照してください。 –

+0

@CharlesDuffy入力のおかげで。私は明日いくつかのマニュアルページを読みます。私はBashとCについて非常に厳密なクラスを取ったが、それはおそらく5ヶ月前であり、それ以来何もしていないので、現時点では私は完全に練習していない! –

答えて

1

私が正しく理解し、あなたは[name][type]の間で名を抽出し、新しい最後のCSVとして追加したい場合。

sed -e 's/.*\[name\] \(.*\) \[type\].*/&,\1/' < input 

お知らせ真ん中に\(.*\)[name][type]間のテキストをキャプチャ

を:。。列あなたはキャプチャグループを使用していることを行うことができます

置換文字列の&は一致した文字列を表します。一致した文字列は、行全体で、パターンの開始と終了は.*で終わります。 ,はリテラルカンマで、\1は最初のキャプチャグループの内容を表し、部分は\(...\)にマッチします。

+0

これは、感謝しました。つまり、macOSユーザは警告を避けるために、sedなどのツールを使用するときはLC_ALL = Cを追加する必要があります。 –

+1

不要です。環境設定によって異なります。私はOSXでもあり、それを追加する必要はなく、 'LC_ALL = en_US.UTF-8' – janos

+0

が面白いです - もっと標準的なSEDを使うようにマシンをセットアップするために特別なことをしましたか?それともBSD版を使っているSierraにいるのでしょうか? –