awkを使用してすべての特殊文字を分割してエスケープする方法

awkを使用してすべての特殊文字を分割してエスケープする方法

分割を使ってchar配列を作成しようとしていますが、これまではうまくいきます。

問題は、入力文字列の文字の前に\があるときです。 \ は、次の文字をエスケープして失われ、配列で考慮されないため、文字とは見なされません。

目標は、後で使用するためにすべてをcharArrayに保存することです。

function getLineChars {
   l=1
   for line in ${fileLinesArray[@]}; do
      charArray=$(echo | awk -v str="${line}" '{
         split(str, lineChars, "")
         for (i=1; i<=length(str); i++) {
            printf("%s ", lineChars[i])
         }
      }')
      l=$(($l+1))
      echo "${charArray[@]}"
   done
}

したがって、最も重要なのは、この場合を除いて、すべての特殊文字または奇妙な文字を配列として印刷することです。

3\zKhj awk: warning: escape sequence `\z' treated as plain `z'

配列の結果は次のとおりです。

3 z K h j

\ 文字が欠落している配列に含める必要があります。

これについて何ができますか? awkを使ってみても大丈夫ですか?それとも別のものを提案しますか?

よろしくお願いします。

ベストアンサー1

使用する必要がある場合は、ここに文字列をawk入力してください。${line}

function getLineChars {
   l=1
   for line in "${fileLinesArray[@]}"; do
      charArray=$( awk '{ split($0, lineChars, "")
                          for (i=1; i<=length($0); i++) {
                              printf("%s ", lineChars[i])
                          }
                        }' <<< "${line}" )
      l=$(($l+1))
      echo "${charArray[@]}"
   done
}

テスト運転してみてください:

$ fileLinesArray=( '3\zKhj' )
$ getLineChars
3 \ z K h j

しかし、中には何が含まれていますかcharArray[@]

$ typeset -p charArray
declare -- charArray="3 \\ z K h j "

実際には末尾のスペースがある文字列です。

文字配列が本当に必要な場合charArray=$( awk ... )に変更してくださいcharArray=( $( awk ... ) )。変更してテストしてみてください。

$ getLineChars                                                                           
3 \ z K h j

$ typeset -p charArray
declare -a charArray=([0]="3" [1]="\\" [2]="z" [3]="K" [4]="h" [5]="j")

これで実際の文字配列ができました。


次のように簡単なものを選択することもできます。

function getLineChars {
   l=1
   for line in "${fileLinesArray[@]}"; do
      mapfile -t charArray < <( grep -o . <<< "${line}" )
      l=$(($l+1))
      echo "${charArray[@]}"
   done
}

メモ:使用するように更新されましたmapfile(同義語readarray、Ed Mortonに感謝します)。

テスト運転してみてください:

$ getLineChars
3 \ z K h j

$ typeset -p charArray
declare -a charArray=([0]="3" [1]="\\" [2]="z" [3]="K" [4]="h" [5]="j")

あるいは、$( grep ... )正規表現と配列を介してBASH_REMATCH[]子プロセス呼び出しを削除することもできます。

getLineChars() {
    l=1
    for line in "${fileLinesArray[@]}"; do 
        [[ "${line}" =~ ${line//?/(.)} ]] && charArray=( "${BASH_REMATCH[@]:1}" )
        l=$(($l+1))
        echo "${charArray[@]}" 
    done
}

どこ:

  • ${line//?/(.)}- 各文字をリテラル文字列に置き換えて、(.)各文字のキャプチャグループを提供します(注:doいいえ二重引用符で囲んでください)
  • "${BASH_REMATCH[@]:1}"- インデックス== 1で始まり、配列の最後まで行くすべての配列項目を取得します。

テスト運転してみてください:

$ getLineChars
3 \ z K h j

$ typeset -p charArray
declare -a charArray=([0]="3" [1]="\\" [2]="z" [3]="K" [4]="h" [5]="j")

$ typeset -p BASH_REMATCH
declare -a BASH_REMATCH=([0]="3\\zKhj" [1]="3" [2]="\\" [3]="z" [4]="K" [5]="h" [6]="j")

おすすめ記事