単純なスクリプトをリファクタリングしてパイプ可能にする方法(標準出力から入力を取得する)

単純なスクリプトをリファクタリングしてパイプ可能にする方法(標準出力から入力を取得する)

次のスクリプトがあります。

#!/bin/bash

file=$1

echo "Phone:" 
read phone
echo
echo "Column:"
read column
echo
echo "New Value:"
read value
echo

index=$(cat $file | grep -n $phone | cut -d: -f1)

cat "$file" | awk -v idx="$index" -v col="$column" -v value="$value" -F ',' '{if (NR==idx) {for(i=1;i<=NF;i++) {if (i==col) $i=value; printf("%s%s", $i, (i==NF ? "\n":FS))}} else print}'

echo

exit 0

ファイルを受け取り、ユーザーに数値、列、および新しい値を求めるプロンプトを表示し、その特定のフィールドを更新します。私の問題は、次のように呼び出す必要があるということです。

./update.sh data.csv

スクリプトをエイリアスに変換し、ユーザーに値を求める代わりにフラグを使用してパイプできるようにしたいので、カスタムフラグ(列の場合は-c、値の場合は-v、フィルター処理されたパターンの場合は-e)を追加しました。たとえば、

cat data.csv | update -c 2 -v "value" -e "pattern"

誰かがスクリプトをフラグ付きエイリアスに変換する方法を案内できますか? (エイリアスはコマンドを参照します。エイリアスを誤って使用した可能性があります。)

そして私はまだbash、awk、linuxを学んでいるので、私が間違っているか、非効率的にやっている部分を見つけたら修正してください。

事前にありがとう

ps おそらく役に立つかもしれません。 data.csvは次のとおりです。

444-555-7777, Max,Weaver, personal:friend:musician
111-222-6665, Craig,Kowalick,office:friend
888-797-2345,Tom, O’Brien, personal:family:musician:midnightsociety

答え1

使用選択項目のインポートパラメータを解析し、awkCSVフィールドと同様に一致させます(例:テストされていません)。

#!/usr/bin/env bash

while getopts ":p:c:v:e:" arg; do
    case $arg in
        p) phone=$OPTARG ;;
        c) col=$OPTARG ;;
        v) val=$OPTARG ;;
        e) ere=$OPTARG ;;
        *) printf 'Unknown argument "%s"\n' "$arg" >&2
           exit 1
           ;;
    esac
done
shift $((OPTIND-1))

次に、awkを使用してCSVで目的の操作を実行します。たとえば、(もう一度テストされておらず、単なる例であり、実際に目的のタスクを実行する意図はありません。上記の変数は単に使用方法を示すことです)。

awk -v phone="$phone" -v col="$col" -v val="$val" -v ere="$ere" '
    BEGIN { FS=OFS="," }
    ($1 == phone) && ($0 ~ ere) && ($col == val) {
        print "Matched: " $0
    }
' "${@:--}"

これは"${@:--}"、ファイル名が渡されると awk に filename から読み取るように指示し、そうでない場合は stdin から読み取るように指示します。

上記のように、awkスクリプトで使用する前にすべての必須変数が入力されていることを確認するには、シェルスクリプトまたはawkスクリプトにいくつかのコードを追加する必要があります。 getoptsループとawk呼び出しの間に次のシェルコードを追加できます。

while [[ -z "$phone" ]]; do
    echo "Phone:" 
    read -r phone
done

変数がプロンプト+応答で満たされていることを確認してください(コマンドラインでまだ設定されていない場合)。

私は上記の質問の「パターン」を介して完全な行拡張正規表現マッチングを実行したいと思います。これが、関連する変数ereまたはpat同様の名前を指定した理由です。直観に反することはわかりますが、要件を指定したり、パターンマッチングコードを書くときに「パターン」という単語を使用しないでください。まるで自動車販売店に行ってセールスマンに「自動車」を買いたいと言っているように、とても曖昧です。どのコンテキストでどのパターンを一致させるかを具体的に知るには、次を参照してください。パターンに一致するテキストを見つける方法

関連情報