以下の文字列があります:
/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
主な問題以外にも多くの問題があります。
ambiguous redirect
なぜならコードに二重引用符がありません。- を使用したリダイレクトは、
<
ファイルからデータを取得します。文字列がファイル (パス) を指していません。Bash では、を使用して文字列からデータを取得できます<<<
。 function
は予約語です。関数に名前を付ける方法はありますfunction
が、それ以上の使用は不便です。- (コメント内の用語) 関数は子ではありません。
- 関数は ではなく、名前で呼び出されます
bash -c
。他の質問に対する私の答え適用されます。 - すると、最初の引数は
$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"
しかし、最後の「フィールド」には末尾の改行文字が含まれます ( の動作によって表示されます
<<<
)。 を使用してすべての区切り文字を改行に変換し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
。