Skip to content

Instantly share code, notes, and snippets.

@naogify
Last active December 18, 2024 04:33
Show Gist options
  • Select an option

  • Save naogify/4a02e08251674e0bafdcfaddd2efdfbc to your computer and use it in GitHub Desktop.

Select an option

Save naogify/4a02e08251674e0bafdcfaddd2efdfbc to your computer and use it in GitHub Desktop.
bash check_and_rename_attribute.sh <変換したい属性名> で実行すると、その属性名がないShapeファイルを探し、指定した属性名を変換するシェルスクリプトです。
#!/bin/bash
# スクリプト名: check_and_rename_attribute.sh
# 説明: 指定された属性名がシェープファイル内に存在するかを確認し、存在しない場合はユーザーに選択させて属性をリネームし、新しいシェープファイルを作成する。
# 修正したファイルを作成した後、元のファイルを削除するかをユーザーに確認する。
# エンコーディングの設定
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
# 必要なツールの確認
for cmd in ogrinfo ogr2ogr jq; do
if ! command -v "$cmd" &> /dev/null; then
echo "エラー: $cmd コマンドが見つかりません。必要なツールをインストールしてください。"
exit 1
fi
done
# 引数の確認
if [ $# -ne 1 ]; then
echo "使用方法: $0 <新しい属性名>"
echo "例: $0 Max_Rank"
exit 1
fi
ATTRIBUTE_NAME="$1"
# 属性名の長さチェック(シェープファイルの制限)
if [ ${#ATTRIBUTE_NAME} -gt 10 ]; then
echo "エラー: 属性名 '$ATTRIBUTE_NAME' は10文字を超えています。シェープファイルの制限によりリネームできません。"
exit 1
fi
echo "指定された新しい属性名: '$ATTRIBUTE_NAME'"
echo ""
# カレントディレクトリ以下のすべてのシェープファイルを検索
shapefiles=$(find . -type f -iname "*.shp")
# シェープファイルが見つからない場合の処理
if [ -z "$shapefiles" ]; then
echo "シェープファイルが見つかりませんでした。"
exit 1
fi
# 属性名の存在状況を記録する配列
declare -a files_with_attribute
declare -a files_without_attribute
# 各シェープファイルについて属性一覧を取得し、指定された属性の存在をチェック
for shp in $shapefiles; do
echo "----------------------------------------"
echo "シェープファイル: $shp"
# .dbf ファイルの存在確認
dbf_file="${shp%.shp}.dbf"
if [ ! -f "$dbf_file" ]; then
echo " エラー: .dbf ファイルが存在しません: $dbf_file"
files_without_attribute+=("$shp")
continue
fi
# ogrinfo を JSON 出力モードで実行
json_output=$(ogrinfo -json "$shp" 2>/dev/null)
# ogrinfo の実行が成功したか確認
if [ $? -ne 0 ]; then
echo " エラー: ogrinfo の実行に失敗しました。"
files_without_attribute+=("$shp")
continue
fi
# jq を使用してフィールド名を抽出
fields=$(echo "$json_output" | jq -r '.layers[0].fields[].name' 2>/dev/null)
# フィールド名が取得できたか確認
if [ -z "$fields" ]; then
echo " エラー: 属性情報の取得に失敗しました。"
files_without_attribute+=("$shp")
else
echo " 属性一覧:"
echo "$fields" | while read -r field; do
echo " - $field"
done
# 指定された属性名が存在するかチェック
if echo "$fields" | grep -iwq "$ATTRIBUTE_NAME"; then
echo " ※ 属性名 '$ATTRIBUTE_NAME' は存在します。"
files_with_attribute+=("$shp")
else
echo " ※ 属性名 '$ATTRIBUTE_NAME' は存在しません。"
files_without_attribute+=("$shp")
fi
fi
done
echo ""
echo "========================================"
# 属性名が存在しないシェープファイル
if [ ${#files_without_attribute[@]} -ne 0 ]; then
# ユーザーに修正するシェープファイルを選択させる
echo ""
echo "属性名 '$ATTRIBUTE_NAME' を追加または既存の属性をリネームするシェープファイルを選択してください。"
# 選択肢に "キャンセル" を追加
select selected_shp in "${files_without_attribute[@]}" "キャンセル"; do
if [ "$selected_shp" == "キャンセル" ]; then
echo "処理をキャンセルしました。"
exit 0
elif [ -n "$selected_shp" ]; then
echo "選択されたシェープファイル: $selected_shp"
break
else
echo "無効な選択です。もう一度選択してください。"
fi
done
# ogrinfo を JSON 出力モードで実行
json_output=$(ogrinfo -json "$selected_shp" 2>/dev/null)
# ogrinfo の実行が成功したか確認
if [ $? -ne 0 ]; then
echo " エラー: ogrinfo の実行に失敗しました。"
exit 1
fi
# jq を使用してフィールド名を抽出
fields=$(echo "$json_output" | jq -r '.layers[0].fields[].name' 2>/dev/null)
# フィールド名が取得できたか確認
if [ -z "$fields" ]; then
echo " エラー: 属性情報の取得に失敗しました。"
exit 1
fi
# ユーザーにリネームする属性を選択させる
echo ""
echo "リネームする既存の属性を選択してください:"
# 属性名の選択肢を生成
IFS=$'\n' read -d '' -r -a field_array <<< "$(echo "$fields" | grep -v '^$')"
# フィールドが存在しない場合の処理
if [ ${#field_array[@]} -eq 0 ]; then
echo "エラー: フィールドが見つかりません。"
exit 1
fi
select selected_field in "${field_array[@]}" "キャンセル"; do
if [ "$selected_field" == "キャンセル" ]; then
echo "処理をキャンセルしました。"
exit 0
elif [ -n "$selected_field" ]; then
echo "選択された属性: $selected_field"
break
else
echo "無効な選択です。もう一度選択してください。"
fi
done
# リネームの実行
echo ""
echo "属性 '$selected_field' を '$ATTRIBUTE_NAME' にリネームします。"
echo "※ 注意: この操作は新しいシェープファイルを作成します。元のファイルは変更されません。"
# 新しいシェープファイル名の設定
base_name="${selected_shp%.shp}"
new_shp="${base_name}_modified.shp"
# レイヤー名の取得
layer_name=$(echo "$json_output" | jq -r '.layers[0].name')
# レイヤー名が空でないことを確認
if [ -z "$layer_name" ]; then
echo "エラー: レイヤー名が取得できませんでした。"
exit 1
fi
# フィールドの存在を確認
existing_fields=$(echo "$json_output" | jq -r '.layers[0].fields[].name')
# SELECT文の作成
SELECT_FIELDS=""
for FIELD in $existing_fields; do
if [ "$FIELD" == "$selected_field" ]; then
SELECT_FIELDS+="\"$FIELD\" AS \"$ATTRIBUTE_NAME\", "
else
SELECT_FIELDS+="\"$FIELD\", "
fi
done
# 末尾のカンマとスペースを削除
SELECT_FIELDS=${SELECT_FIELDS%, }
# SQLクエリの構築
SQL="SELECT $SELECT_FIELDS FROM \"$layer_name\""
# 出力シェープファイルが既に存在する場合は削除
if [ -f "$new_shp" ]; then
echo "Warning: Output shapefile '$new_shp' already exists and will be overwritten."
rm -f "$new_shp"
rm -f "${new_shp%.shp}".*
fi
# ogr2ogrコマンドを実行して新しいシェープファイルを作成
ogr2ogr -f "ESRI Shapefile" "$new_shp" "$selected_shp" -sql "$SQL" -lco ENCODING=UTF-8
if [ $? -ne 0 ]; then
echo "エラー: 新しいシェープファイルの作成に失敗しました。"
exit 1
fi
echo "Success: 属性 '$selected_field' を '$ATTRIBUTE_NAME' にリネームした新しいシェープファイルを作成しました。"
echo "新しいシェープファイル: '$new_shp'"
echo ""
echo "新しいシェープファイル '$new_shp' の属性を確認してください。"
echo "元のシェープファイルは変更されていません。"
echo ""
echo "========================================"
# 元のシェープファイルを削除するか確認
while true; do
read -p "元のシェープファイル '$selected_shp' を削除しますか? (y/n): " yn
case $yn in
[Yy]* )
base="${selected_shp%.shp}"
# 関連するファイルをすべて削除
for ext in shp shx dbf prj cpg; do
file="${base}.${ext}"
if [ -f "$file" ]; then
rm -f "$file"
echo "削除しました: $file"
fi
done
echo "元のシェープファイル '$selected_shp' と関連ファイルを削除しました。"
break
;;
[Nn]* )
echo "元のシェープファイルは削除されませんでした。"
break
;;
* )
echo "Please answer yes or no (y/n)."
;;
esac
done
fi
echo "========================================"
echo "処理が完了しました。"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment