5

空のテキスト行で区切られたテキスト行を含むテキスト ファイルがあります。そのファイルの内容を配列にプッシュし、空の行をセパレーターとして使用したいと考えています。IFS="\n" (または "\r\n" など) を試しましたが、うまくいかなかったので、代わりに空の行をファイルにない文字に置き換えると思ったので、スペイン語の逆疑問符 (\xBF) を拾いました。

sed 's/^$/'$(echo -e "\xBF")'/'))

それで、ファイルをスライスして配列に入れるために使用する文字があります。

ここで、$IFS を変更して、逆疑問符を使用して配列のデータをスライスする必要があります。

入力すると

IFS=$(echo -e "\xBF")

コマンドラインでは問題なく動作します

 echo "$IFS"
¿

しかし、末尾に read -a を付けてそのコマンドを入力すると、何もしません:

[user@machine ~]$ IFS=$(echo -e "\xBF") read -a array <<< "$var"
[user@machine ~]$ echo "$IFS"
[user@machine ~]$

$var には値があるので、それは奇妙です。

さらに驚くべきことに、取得直後に IFS の値を確認すると、次のようになります。

[user@machine ~]$ echo -n "$IFS" | od -abc
0000000  sp  ht  nl
    040 011 012
         \t  \n
0000003
[user@machine ~]$ 

これは IFS のデフォルト値です。

IFSにはどんな文字でも使用できると確信していますよね?

または、空の行に基づいて分割して配列内のファイルを分割するためのトリックがあれば、私は興味があります! (それでも、理解のためにこれの一番下に行きたいと思います)。

どうもありがとうございました。良い週末をお過ごしください :)

4

2 に答える 2

5

このスクリプトは、あなたが望むことをするはずです:

#!/bin/bash

i=1
s=1
declare -a arr
while read -r line 
do
    # If we find an empty line, then we increase the counter (i), 
    # set the flag (s) to one, and skip to the next line
    [[ $line == "" ]] && ((i++)) && s=1 && continue 

    # If the flag (s) is zero, then we are not in a new line of the block
    # so we set the value of the array to be the previous value concatenated
    # with the current line
    [[ $s == 0 ]] && arr[$i]="${arr[$i]}
$line" || { 
            # Otherwise we are in the first line of the block, so we set the value
            # of the array to the current line, and then we reset the flag (s) to zero 
            arr[$i]="$line"
            s=0; 
    }
done < file

for i in "${arr[@]}"
do
   echo "================"
   echo "$i"
done 

テスト ファイル:

$ cat file
asdf dsf s dfsdaf s
sadfds fdsa fads f dsaf as

fdsafds f dsf ds afd f saf dsf
sdfsfs dfadsfsaf

sdfsafds fdsafads fd saf adsfas
sdfdsfds fdsfd saf dsa fds fads f

出力:

================
asdf dsf s dfsdaf s
sadfds fdsa fads f dsaf as
================
fdsafds f dsf ds afd f saf dsf
sdfsfs dfadsfsaf
================
sdfsafds fdsafads fd saf adsfas
sdfdsfds fdsfd saf dsa fds fads f

アップデート:

で始まる行を無視するには#、次の行を の後に追加しますdo

[[ $line =~ ^# ]] && continue
于 2013-08-30T18:54:38.817 に答える
4

まず第一に、設計上、 で設定された変数はスクリプトvar=foo commandでのみ使用可能にcommandなり、残りのスクリプトでは設定されません。

あなたの問題については、最初の区切り文字 ( 、デフォルト: 改行)readまでレコードを読み取り、それを でフィールドに分割します。-d$IFS

アイテムをループするには、次を使用できます

sed -e 's/^$/\xBF/' | while read -d $'\xBF' var
do
    printf "Value: %s\n-----\n" "$var"
done

それらをすべて文字列から配列に読み込むには、NUL バイトのように、おそらく持っていない文字まで読み込むことができます。

IFS=$'\xBF' read -d '' -a array <<< "$var"
于 2013-08-30T18:47:18.057 に答える