Bash

數組的訪問元素

  • August 24, 2021

我有以下從 mysql 檢索資訊的腳本

#!/bin/bash
set -f       
IFS=$'\n'

arr=($(sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users"))


for i in "${arr[@]}"
do
  echo "$i}"
done

當我執行上一個腳本時,我得到:

id      firstname       lastname        phonenumber     password        email   ip}
5       User    User    111111111111    Passtest1       testuser@gmail.com      147.236.147.91}

這是問題:我想在執行時列印一個鍵值:

#!/bin/bash

set -f       
IFS=$'\n'    

arr=($(sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users"))


echo ${arr[ip]}

然後我得到:

id      firstname       lastname        phonenumber     password        email   ip

如何列印 id 值,在這種情況下是5

首先,我是否建議您通過shellcheck執行所有 shell 腳本——在許多 Linux 發行版上也可以作為獨立程序使用——以檢測語法錯誤。echo $i}eg 看起來像一個錯字,它只“有效”,因為它$i與 相同${i},並且額外的}“only”導致}附加到預期輸出的雜散。

其次,這裡似乎對數組和變數的使用存在誤解。您想要列印ip從輸出的“實際數據行”標記的最後一列。您的使用

echo ${arr[ip]}

但是將不起作用,因為您既沒有聲明(如 中declare -A arr)也沒有“填充”arr關聯數組,這意味著像這樣取消引用數組將不起作用 - shell 將在這裡期望一個數字數組索引。如果您提供一個文本字元串(如ip),則行為將取決於 shell,儘管它可能會將其解釋為變數名,發現該變數未定義(即計算為空字元串),然後僅列印數組的第一個條目(在您的情況下為第一行)。

此外,即使您將數組聲明為關聯數組,“列標題”與“數組索引”的匹配也不會自動進行;如果您想要有針對性的訪問權限,您必須手動完成。

第三,在大多數情況下,使用文本處理工具(例如awk在 shell 中進行)可以更好地執行文本處理。由於您想忽略標題行並列印第二行的最後一列,我建議

sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users" | awk 'NR==2{print $7}'

它將通過一個程序處理sudo呼叫mysql命令的呼叫的輸出,該awk程序僅處理第二行(條件NR==2)並在遇到該行時列印第 7 列。

第四,最好的選擇仍然是使用數據庫工具本身來選擇數據。我不是 SQL 專家,但我認為這樣的查詢

mysql -u root -h localhost -e "USE mydb; SELECT ip FROM users WHERE id='5'"

應該可以工作(但請在生產使用之前用一個不重要的例子進行驗證)。

引用自:https://unix.stackexchange.com/questions/665845