BashでIFSを2バイト値に設定するにはどうすればよいですか?
IFS=',;'
区切り記号は、区切り記号の代わりに単純な部分と/または単純な2つの,
部分の間にある各部分ですか?ソリューションを提供できるようにシミュレーション/解決方法を実行するには?前にありがとう;
,;
答え1
zsh
代わりに(plit用)パラメータ拡張フラグをbash
使用して切り替えることができます。s
s
$ string='foo,;bar,;,;baz'
$ words=("${(@s[,;])string}")
$ typeset -p words
typeset -a words=( foo bar '' baz )
これは分けるいいえ定義するはIFS分割(単一文字のみを含む)ではなく空の文字列foo,;
に分割されます。foo
foo
bash
また、bash
(and zsh
、すべてのシェルではありませんが)でスプレー数値~の$IFS
, いいえバイト。たとえば、を使用すると、IFS='é'
2バイトでエンコードされたロケール(たとえば、文字が最も一般的なUTF-8にマップされるロケール)でもStéphane
分割されます。St
phane
é
答え2
bash(バージョン4.3+)機能:
split() {
local string=$1 fs=$2
local -n fields=$3
fields=()
while [[ $string =~ (.*)"$fs"(.*) ]]; do
fields=( "${BASH_REMATCH[2]}" "${fields[@]}" )
string=${BASH_REMATCH[1]}
done
fields=( "$string" "${fields[@]}" )
}
使用法:
$ string="field1,;field2,field2b,;field3a;field3b,;,;field4"
$ split "$string" ",;" result
$ declare -p result
declare -a result=([0]="field1" [1]="field2,field2b" [2]="field3a;field3b" [3]="" [4]="field4")
区切り文字を引用符で囲んだCSV解析を実装しようとする多くの素朴な試みと同様に、失敗します。
$ split 'Thoughtfully, he said "Hello, friend."' , x
$ declare -p x
declare -a x=([0]="Thoughtfully" [1]=" he said \"Hello" [2]=" friend.\"")
答え3
IFS
は単一文字区切り文字のセットなので、IFS=,;
または;
すべて,
区切り文字として使用され、a,b,;c;d
5つのフィールドがあります。その組み合わせを単一の区切り文字としてのみ使用するには、,;
手動で実行する必要があります。 1つの方法は、,;
ペアを入力の単一文字に置き換えることですIFS
。
s='a,b,;c;d'
IFS=#
fields=(${s//,;/#})
${s//,;/#}
すべての部分文字列を,;
次に置き換え#
、引用符なしで結果を展開します。これで、配列にsumがfields
含まれます。また、生成された単語をglob(ファイル名ワイルドカード)として使用することに注意してください。これを防ぐために/を使用したいかもしれませんが、に割り当てられているだけでなく、グローバル効果もあることに注意してください。a,b
c;d
set -f
set -o noglob
IFS
sed
または、特に開始するパイプラインがある場合は、次のものを使用できます。
sed -e 's/,;/#/g'