2017-03-28 17 views
-1

こんにちは私は仕事のために少しbashスクリプトを書いています。しかし今、私は立ち往生しています。私はちょうどあなたのコードを表示し、説明してみましょう:ループトラフ配列用のBash

# I have an `array` with names 
NAMES=(Skypper Lampart Shepard Ryan Dean Jensen) 

今私は反復が2つの番号と名前を持つファイルであると私はちょうどたい名前を置き換える名前

for ((i = 0; i < 6; i++)); do 
    COMMAND="sed -i ${i+2}s/.*/${NAMES[${i}]}" 
    ${COMMAND} config.txt 
done 

config.txtトラフたいです。

1 
2 
Name 1 
Name 2 
Name 3 
Name 4 
Name 5 
Name 6 

私の問題は、どのように私は$i + 2を作ることができますfor -loopにありますか?

1 
2 
Skypper 
Lampart 
Shepard 
Ryan 
Dean 
Jensen 
+0

を置き換えバリアントあなたの予想される出力は何ですか? – sat

+0

@sat予想される出力を追加しました – WasteD

+1

sedが置換を実行するインラインファイルは何ですか? 数値が$(($ i + 2))の場合 – louigi600

答えて

1

バッシュは読書アレイで良いです(あなたが持っている可能性が何かを簡単に検索):I $iが1であれば、それは3

の予想される出力でなければなりません。

ような何か試してみてください:意図したように、単にコマンドを使用し、あなたはあなたが何をしているか知っている限り、変数内のコマンドを配置することも剥がれてくることができていることがわかります

for idx in "${!NAMES[@]}" 
do 
    sed -i "$((idx + 2))s/.*/${NAMES[idx]} $idx/" config.txt 
done 

を:)

あなたがかもしれませんまた、インデックスが0から始まって1から始まることを覚えておく必要があります。

+0

問題は配列ではありませんが、私の質問に対する解決策はこの '$((idx + 2))' – WasteD

+0

です。もう1つの問題は 'idx'が3なら' 3 + 2 = 5'です。 'sed'の間違った行につながります。 – sat

+0

私のスクリプトでは、 'for((i = 0; i <6; i ++))'とsedは 'sed -i $(($ {i} + 3))s /.*/$ {DATA [$ {i}]} 'それは働きます! – WasteD

1

あなたが達成したいことを理解していれば(NAMES配列の文字列で "Name"を置き換えます。配列のインデックスが0から始まり、 3行目) - 汚れ2つの空の文字列を配列の先頭に追加し、必要な位置からループを開始することです。

+0

Arrayインデックスは '-i'の後の数字だけではありませんファイル内の行番号3から開始してください。 – WasteD

+1

ああ、その場合、bash算術を検索する必要があります。私はそれが$ {(i + 2)}か$ {((i + 2))}だと思いますが、今すぐbashにアクセスすることはできません。 –

+0

ええ、それは '$(($ {i} + 3))' – WasteD

1

使用この:

NAMES=(Skypper Lampart Shepard Ryan Dean Jensen) 
line=2 # Need to skip first 2 lines 
for name in "${NAMES[@]}" 
do 
    ((line++)) 
    sed -i "${line}s/.*/$name/g" config.txt 
done 
1

あなたが周りにこのような何か試すことができます。

NAMES=(Skypper Lampart Shepard Ryan Dean Jensen) 
for ((i = 0; i < 6; i++)); do 
    b=$(($i+2)) 
    COMMAND="sed -i $b s/.*/${NAMES[${i}]}" 
    echo $COMMAND 
# ${COMMAND} config.txt 
done 

私に次のような出力できます:

# sh test.sh 
sed -i 2 s/.*/Skypper 
sed -i 3 s/.*/Lampart 
sed -i 4 s/.*/Shepard 
sed -i 5 s/.*/Ryan 
sed -i 6 s/.*/Dean 
sed -i 7 s/.*/Jensen 
+0

うん、今解決しました。 – WasteD

1

少し遅れて答えを。 .. :)

コードでsedをn回呼び出す。これは非効率的です。したがって、sedの代わりにedを使用して、別のソリューションを提案しています。 (30年前にBSD 2.9で古き良き時代のように:))。このため

、アプローチ:ed

  • ため

    1. 最初の作成コマンドは、上記

      === [config.txt before] === 
      1 
      2 
      Name 1 
      Name 2 
      Name 3 
      Name 4 
      Name 5 
      Name 6 
      === [commands for execution ]=== 
      /Name/s//Skypper/ 
      /Name/s//Lampart/ 
      /Name/s//Shepard/ 
      /Name/s//Ryan/ 
      /Name/s//Dean/ 
      /Name/s//Jensen/ 
      w 
      q 
      ===[ config.txt after ]=== 
      1 
      2 
      Skypper 1 
      Lampart 2 
      Shepard 3 
      Ryan 4 
      Dean 5 
      Jensen 6 
      
      から1つのエディタの呼び出しに
    # it is good practice not using UPPERCASE variables 
    # as theycould collide with ENV variables 
    
    names=(Skypper Lampart Shepard Ryan Dean Jensen) 
    file="config.txt" 
    
    #create an array of commands for the "ed" 
    declare -a cmd 
    for name in "${names[@]}"; do 
        cmd+=("/Name/s//$name/") 
    done 
    cmd+=(w q) 
    
    echo "=== [$file before] ===" 
    cat "$file" 
    
    echo "=== [commands for execution ]===" 
    printf "%s\n" "${cmd[@]}" 
    
    #execute the prepared command in the "ed" 
    printf "%s\n" "${cmd[@]}" | ed -s "$file" 
    
    echo "===[ $file after ]===" 
    cat "$file" 
    

    出力それらを実行します

    行番号で

    names=(Skypper Lampart Shepard Ryan Dean Jensen) 
    file="config.txt" 
    
    #create an array of commands for the "ed" 
    declare -a cmd 
    n=3 
    for name in "${names[@]}"; do 
        cmd+=("${n}s/.*/$name/") 
        let n++ 
    done 
    cmd+=(w q) 
    
    echo "=== [$file before] ===" 
    cat "$file" 
    
    echo "=== [commands for execution ]===" 
    printf "%s\n" "${cmd[@]}" 
    
    #execute the prepared command in the "ed" 
    printf "%s\n" "${cmd[@]}" | ed -s "$file" 
    
    echo "===[ $file after ]===" 
    cat "$file" 
    

    出力

    === [config.txt before] === 
    1 
    2 
    Name 1 
    Name 2 
    Name 3 
    Name 4 
    Name 5 
    Name 6 
    === [commands for execution ]=== 
    3s/.*/Skypper/ 
    4s/.*/Lampart/ 
    5s/.*/Shepard/ 
    6s/.*/Ryan/ 
    7s/.*/Dean/ 
    8s/.*/Jensen/ 
    w 
    q 
    ===[ config.txt after ]=== 
    1 
    2 
    Skypper 
    Lampart 
    Shepard 
    Ryan 
    Dean 
    Jensen 
    
  • +0

    まず第一に、問題は私の場合、すでに名前が違っているだけではありません:/そして、第二に私は 'ed'を知りませんでした。 – WasteD

    +1

    @WasteD質問に対する回答を作成しました。質問には、入力には 'Name'文字列だけが含まれています。私の答えを修正することは自明ですが、私は何の入力があるのか​​わかりません... – jm666

    +0

    ええ、私は理解しているが、istは今解決した:) – WasteD