Bashの2つの単語の間に区切り記号を追加する

Bashの2つの単語の間に区切り記号を追加する

私のクエリは次のとおりです

QUERY="SELECT 'Your Name:', FullName, 'Your Phone:', Phone, 'Email:', Email FROM Table1 JOIN  WHERE EmpID=001;"

私が得た結果は次のとおりです。

Your Name: Samanta Your Phone: 111-111-1111 Email: [email protected]

しかし、印刷するときは、次のような出力が必要です。

Your Name: Samanta
Your Phone: 111-111-1111
Email: [email protected]

私はこれを試しました:

出力 =executeSQLQuery "$QUERY" | tr -c ' ' '\n'

動作しません。

答え1

output=executeSQLQuery "$QUERY" |sed 's/: [^ ]* /& \n/g'

上記のコマンドは以下を生成します。

user@user:~> z="Your Name: Samanta Your Phone: 111-111-1111 Email: [email protected]"
user@user:~> echo $z | sed 's/: [^ ]* /& \n/g'
Your Name: Samanta  
Your Phone: 111-111-1111  
Email: [email protected]
user@user:~> 

このコマンドは、コロン(':')、スペース、およびスペース以外のすべての文字で構成される正規表現の一致を使用します。ただし、データに空白文字が含まれていると、コマンドは正しく失敗します。

答え2

これは次のとおりですXYの問題- 2つの単語の間に区切り文字を追加したいと言いましたが、実際に望むのは、SQLクエリから返されたデータを印刷することです。

あなたの問題は、単純なデータではなく形式化された出力を返すExecutionSQLQuery関数(またはスクリプトまたはプログラム)が原因で発生し、$ QUERY文字列がそれを指示するためにそうするようです。

executeSQLQuery列ヘッダーなしで解析しやすい形式(CSVやタブ区切りなど)でデータを返す関数/スクリプトはありますか?

(つまり、「ではありません。」データ収集と結果の分離を提示)

可能であれば、printf を使用して必要な方法でデータ型を指定できます。たとえば、タブ区切りの出力とbash配列を使用すると、次のようになります。

QUERY="SELECT FullName, Phone, Email FROM Table1 WHERE EmpID=001;"

# disable globbing which would otherwise be performed upon non-quoted
# command substitution (except in zsh):
set -f

# set the input-field-separator to tab and newline (but not space characters)
# execute the query and store the results in the array $output
IFS=$'\t\n' output=($(executeSQLQuery "$QUERY"))

# now print the output array in the format we want.
printf "Your Name: %s\nYour Phone: %s\nEmail: %s\n" "${output[@]}"

以下はmysqlを使った実際の例です。私はあなたが何であるかわかりませんが、ちょうどexecuteSQLQueryテストmysqlデータベース(「ジャンク」と呼ばれる)を作成し、ここにサンプルデータを入力し、次の関数を定義しましたexecuteSQLQuery

$ executeSQLQuery() { mysql --batch --silent junk -e "$@" ;}

--batch注意事項とオプションを参照してください--silent。彼らはmysqlにヘッダーや他のフォーマットなしでデータのみを提供するように指示します。私の資格情報を含む〜/ .my.cnfファイルを生成したため、ユーザー-uとパスワードのオプションはありません。-p

それでは、クエリを実行し、出力配列に含まれている内容を表示してから、printfを使用してきれいに印刷してみましょう。

$ set -f; IFS=$'\t\n' output=($(executeSQLQuery 'Select Fullname,Phone, Email from Table1 where EmpId = 001'))

$ set | grep output
output=([0]="Samantha" [1]="111-111-1111" [2]="[email protected]")

$ printf "Your Name: %s\nYour Phone: %s\nEmail: %s\n" "${output[@]}"
Your Name: Samantha
Your Phone: 111-111-1111
Email: [email protected]

しかし、bashは多次元配列をサポートしていないため、クエリが複数の行を返す場合は[0..2]、[3..5]、[6..8]などを別々のレコードとします。たとえば、テーブル1に2番目のレコードを追加し、すべての行を返すようにクエリを変更しました。これで出力配列は次のようになります。

$ set -f; IFS=$'\t\n' output=($(executeSQLQuery 'Select Fullname,Phone, Email from Table1'))
$ set | grep output
output=([0]="Samantha" [1]="111-111-1111" [2]="[email protected]" [3]="Fred" [4]="222-222-2222" [5]="[email protected]")

しかし全体的にはたくさんDBIライブラリを使用すると、Perlでデータベース操作を簡単に実行できます。何らかの理由でbashを使用したくない場合は、Perlを学び始めることをお勧めします。

答え3

出力の問題は、出力の最初の行に3つの単語(論理的にキーと値のペアにもかかわらず)をグループ化し、次の行に別の3つの単語を、3行目に最後の2つの単語をグループ化することです。

この特定の問題の場合、簡単な方法は次のとおりです。

executeSQLQuery "$QUERY" | awk '{print $1 " " $2 " " $3 "\n" $4 " " $5 " " $6 "\n" $7 " "$8 }'

ただし、通常、次のようにクエリを変更する方が良いです。

SELECT FullName as 'Your name', Phone as 'Your phone', Email FROM Table1 WHERE EmpID=001;

次に、行名と列名を取得し、Perlまたは他の言語で目的の出力を作成します。

関連情報