簡體   English   中英

shell腳本中的遞歸解析和數組

[英]Recursive parsing and arrays in shell script

我打算為我的shell腳本my_script.sh接受一個參數,並使用分隔符解析它的值。 例如,

./my_script.sh a-e,f/b-1/c-5,g/d

意味着我的主分隔符是/和輔助分隔符是-和叔分隔符是, 這里的挑戰是由...分隔的值的數量,或者-不是固定的,而是可變的。 d ,不存在-或者,在所有。 我總是可以解析由/分隔的值:

IFS='/' read -ra list_l1 <<<$1

這樣,我得到了我需要循環的次數。 但是我在list_l1嘗試解析時list_l1 這里,

  1. 我需要看看是否存在-,或者它們是否存在。
  2. 如果有-並且, ,得到的值之后-並通過它/它們作為參數傳遞給另一個腳本(如, a e,f將被作為單獨的參數傳遞給另一個腳本)。
  3. 如果沒有-,只運行另一個沒有參數的腳本(例如,對於d ,另一個腳本運行時沒有任何參數)。

我怎么能這樣做?

更新:

我設法為第一級找到了方法:

IFS='/' read -ra list_l1 <<<$1
for i in "${!list_l1[@]}"; do
    list_l2[$i]="${list_l1[$i]//,/$' '}"
    # This section is a pseudocode of what I would like to do:
    get 'type' from first part (before '-' as in example above)
    if type == 'a':
        pass the with parameters after '-' to another .sh script, discarding the separators '-', ','
    elif type == 'b':
        pass the with parameters after '-' to another .sh script, discarding the separators '-', ','
    elif type == 'c':
        pass the with parameters after '-' to another .sh script, discarding the separators '-', ','
    elif type == 'd':
        pass the with parameters after '-' to another .sh script, discarding the separators '-', ','
    # This section is a pseudocode of what I would like to do:
done

看看這個:

#!/usr/bin/env bash

f() { printf 'I am called with %d arguments: %s\n' "$#" "$*"; }

param='a-e,f/b-1/c-5,g/d'

IFS=/ read -ra a <<< "$param"
for i in "${a[@]}"; do
    IFS=- read -r _ b <<< "$i"
    IFS=, read -ra c <<< "$b"
    f "${c[@]}"    
done
$ ./script
I am called with 2 arguments: e f
I am called with 1 arguments: 1
I am called with 2 arguments: 5 g
I am called with 0 arguments:

根據我對你的問題的理解,我制作了這段代碼:**編輯no1,使用該數組調用另一個腳本**

#!/bin/bash

arg='a-e,f/b-1/c-5,g/d'

# Cuts it in [a-e,f] [b-1] [c5,g] [d]
IFS='//' read -ra list_l1 <<<$arg

echo "First cut on /."
echo "Content of list_l1"
for K in "${!list_l1[@]}"
do
    echo "list_l1[$K]: ${list_l1[$K]}"
done
echo ""

declare -A list_l2
echo "Then loop, cut on '-' and replace ',' by ' '."
for onearg in ${list_l1[@]}
do
    IFS='-' read part1 part2 <<<$onearg

    list_l2[$part1]=$(echo $part2 | tr ',' ' ')
done

echo "Content of list_l2:"
for K in "${!list_l2[@]}"
do
    echo "list_l2[$K]: ${list_l2[$K]}"
done

# Calling another script using these values
echo ""
for K in "${!list_l2[@]}"
do
    echo "./another_script.sh ${list_l2[$K]}"
done

其中給出了以下輸出:

$ ./t.bash 
First cut on /.
Content of list_l1
list_l1[0]: a-e,f
list_l1[1]: b-1
list_l1[2]: c-5,g
list_l1[3]: d

Then loop, cut on '-' and replace ',' by ' '.
Content of list_l2:
list_l2[a]: e f
list_l2[b]: 1
list_l2[c]: 5 g
list_l2[d]: 

./another_script.sh e f
./another_script.sh 1
./another_script.sh 5 g
./another_script.sh 

一些細節:

  • 第一步是切入'/'。 這會創建list_l1。
  • list_l1中的所有元素都以['a','b','c','d',...]開頭。 剪切'/'后每個元素的第一個字母。
  • 然后在' - '上再次切斷這些中的每一個。
  • 切割的第一部分(' - '的左側)成為關鍵。
  • 切割的第二部分(' - '的右邊)成為價值。
  • list_l2使用剛剛計算的鍵和值創建為關聯數組。

這樣,list_l2包含您需要的所有內容,而不必在以后引用list_l1。 如果您需要密鑰列表,請使用${!list_l2[@]} 如果需要值列表,請使用${list_l2[@]}

如果符合您的要求,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM