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ではなくとして参照されます$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"
    

    しかし、最後の「フィールド」には末尾の改行文字が含まれます ( の動作によって表示されます<<<)。 を使用してすべての区切り文字を改行に変換しtrreadarrayそのデフォルト設定 (区切り文字として改行) を使用します。

  • スペースは区切り文字には属さず、保存された値の一部になります。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。予想よりも多くのフィールドがある場合、余分なフィールドが を占有しますextraextraそれらがないと に影響します$wtf3
    • これらの変数を使用できますexport
  • foo|bar|baz|…(または同様の)形式の(多数の)レコードを含むファイル/ストリームを操作する場合は、foo | bar | baz | …をよく理解してくださいawk

関連情報