web-dev-qa-db-ja.com

テキスト行からトークンを抽出する

Bashスクリプトとgrep/awk/sedを使用して、既知のパターンに一致する行を1文字の区切り文字で配列に分割するにはどうすればよいですか。変換token1;token2;token3;token4からa[0] = token1a[3]=token4

5
Jas

[〜#〜] update [〜#〜]この方法で配列を作成することは、IFSが単一の非空白文字である場合にのみ適していることに注意してくださいandデータ文字列に複数の連続した区切り文字はありません。
この問題を回避する方法と同様の解決策については、こちらにアクセスしてください nixとLinuxの質問 ...(そして、IFSについてさらに洞察を得るために読む価値があります。 。


Bash(および他のPOSIXシェル(ash、ksh、zshなど))のIFS(内部フィールドセパレーター)を使用します。

IFSを使用すると、外部呼び出しが回避され、埋め込みスペースが可能になります。

# ==============
  A='token0:token1:token2.y   token2.z '
  echo normal. $A
# Save IFS; Change IFS to ":" 
  SFI=$IFS; IFS=:     ##### This is the important bit part 1a 
  set -f              ##### ... and part 1b: disable globbing
  echo changed $A
  B=($A)  ### this is now parsed at :  (not at the default IFS whitespace) 
  echo B...... $B
  echo B[0]... ${B[0]}
  echo B[1]... ${B[1]}
  echo B[2]... ${B[2]}
  echo B[@]... ${B[@]}
# Reset the original IFS
  IFS=$SFI             ##### Important bit part 2a
  set +f               ##### ... and part 2b
  echo normal. $A

# Output
normal. token0:token1:token2.y token2.z
changed token0 token1 token2.y   token2.z 
B...... token0
B[0]... token0
B[1]... token1
B[2]... token2.y   token2.z 
B[@]... token0 token1 token2.y   token2.z 
normal. token0:token1:token2.y token2.z
7
Peter.O

主な2つのアプローチがあります。 1つはIFSfred.bearによって示されています です。これには、個別のプロセスを必要としないという利点がありますが、入力にシェルにとって特別な意味を持つ文字が含まれている可能性がある場合は、正しく処理するのが難しい場合があります。もう1つのアプローチは、テキスト処理ユーティリティを使用することです。フィールド分割はawkに組み込まれています。

input="token1;token2;token3;token4"
awk -vinput="$input" 'BEGIN {
    count = split(input, a, ";");
    print "first field: " a[1];
    print "second: field" a[2];
    print "number of fields: " count;
    exit;
}'

Awkは、複数の入力を処理する場合に特に適しています。

command_producing_semicolon_separated_data |
awk -F ';' '{
    print "first field: " $1;
    print "second field: " $2;
    print "number of fields: " NF;
}'
$ str="token1;token2;token3;token4"
$ echo $str
token1;token2;token3;token4
$ echo $str | tr ';' ' '
token1 token2 token3 token4
$ arr=( $(echo $str | tr ';' ' ') ) # Populate the tokens into an array
$ echo ${arr[0]}  # Access items by index
token1
$ echo ${arr[2]}
token3
$ echo ${arr[1]}
token2
$ echo ${#arr[@]}  # Length of the array
4
0
Barun