在Linux中如何使用分隔符號分隔子字串?

在Linux中如何使用分隔符號分隔子字串?

我有下面的字串:

/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand

我是 Linux 初學者。如何使用“|”分隔作為分隔符號並在變數中賦值?我將整個字串作為參數傳遞,並且需要單獨拆分/剪切字段。

例如:

function()
{
while read -r record; do
## here i need the fields to cut the fields and assign to a variable #####
done < $0 
}

bash -c function "/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand"

當我嘗試上面的例子時,它拋出了一個錯誤$0: ambiguous redirect

答案1

您可以使用tr分隔符號來分隔

在下面的例子中我們替換|newline

variable=$(echo "/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand" | tr "|" "\n")

echo $variable

您也可以使用

echo yourtext | tr -d "|"

tr 指令

答案2

除了主要問題之外還有很多問題。

  1. ambiguous redirect是因為你的程式碼缺少雙引號
  2. 重定向<從檔案中取得資料。您的字串不指向檔案(路徑)。在 Bash 中,您可以使用<<<.
  3. function是一個保留字。有一種方法可以命名函數function,但進一步使用不方便。
  4. (評論中的術語)函數不是孩子。
  5. 人們可以透過函數的名稱來呼叫函數,而不是透過bash -c.我對你另一個問題的回答適用。
  6. 那麼第一個參數稱為$1, not $0

這段程式碼有效,儘管我不確定它是否正是您想要的:

#!/bin/bash

split_string ()
{
   readarray -t arrayv < <(tr '|' '\n' <<< "$1")
}

split_string '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand'

# now arrayv is an array variable (indexed from 0)
# retrieving few values
echo "${arrayv[0]}"
echo "${arrayv[5]}"
echo "${arrayv[9]}"

筆記:

  • 您用雙引號引用了該字串。請記住,雙引號中的字串會經歷一定的擴展。您的字串不包含任何可以擴展的內容(例如$),因此在這種特殊情況下雙引號是可以的。通常使用單引號來抑制擴充。
  • readarray是 的同義詞mapfile。調用help mapfile來學習。
  • 其他研究素材:<<<,<( … ),陣列
  • 沒有辦法將export數組變數加入環境。
  • 我們可以告訴readarray使用|作為分隔符號:

     readarray -t -d '|' arrayv <<< "$1"
    

    但最後一個「字段」將包含一個尾隨換行符(它會因為<<<工作原理而出現)。我將所有分隔符轉換為換行符tr,然後readarray使用其預設值(換行符作為分隔符)。

  • 空格不屬於分隔符,它們成為儲存值的一部分。使用sed代替tr將帶有相鄰空格的分隔符號的子字串轉換為單一換行符。該readarray …行將是:

    readarray -t arrayv < <(sed 's/ *| */\n/g' <<< "$1")
    
  • 如果您只想使用該函數一次,則根本不需要函數。這一行(在任何函數之外)將完成這項工作:

    readarray -t arrayv < <(tr '|' '\n' <<< '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand')
    

    我定義了一個函數(然後只使用了一次),因為您試圖定義一個函數。

  • 如果您的輸入字串由固定數量的欄位組成且這些欄位具有含義,則最好將它們指派給名稱具有含義的不同(非陣列、常規)變數。例子:

    IFS='|' read -r path1 path2 path3 path4 path5 ip path6 wtf1 wtf2 wtf3 extra < <(sed 's/ *| */|/g' <<< '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand')
    echo "$ip"
    echo "$wtf3"
    

    具體注意事項:

    • 這裡我們明確地使用|作為分隔符號。當我們使用 時read,尾隨換行符(由於某些重定向和工具的工作方式而出現)不僅是無害的,而且是必需的。
    • 我添加了extra變數。如果欄位多於預期,則多餘的欄位將被佔用extra。沒有extra它們就會影響$wtf3
    • 您可以使用export這些變數。
  • foo|bar|baz|…如果您要以(或類似)的形式操作包含(許多)記錄的文件/流,foo | bar | baz | …那麼請熟悉awk.

相關內容