IFS=$'?\n'
for line in $(cat "./newfiletoread")
do printf "${line}\n"
done
ファイルの内容は次のとおりです。こんにちは!大丈夫ですか?人生はどうですか?私の人生は冬の朝ほど退屈です!
上記のコードは「?」または '!' が見つかったら、ファイルの内容を分割します。 'または'/n'なら大丈夫です。ただし、拡張中にシェルはファイルからこれらの文字を削除します。以下は私が得た結果です。
Hello there
How are you doing
How is life
Mine is as boring as a winter morning
コマンドが実行される前にこれらのIFS値を空白に置き換えると、シェルが機能することがわかります。分割中にこれらの区切り文字を保持する方法はありますか?以下のような出力を得たいです。
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
答え1
文字列分割についてどこかで読みました。split
何を捨てるべきかを知るときに使用し、何を維持するべきかを知るときに正規表現を使用します。またはそのようなもの。
シェル単語分割を使用する際の問題$IFS
は、その変数のすべての文字が分割に使用され、どの文字かわからないことです。
Bashでは、次のように書くことができます。
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
line=${line//\?/$'"?\n'}
line=${line//\!/$'"!\n'}
echo "$line"
Hello there"!
How are you doing"?
How is life"?
Mine is as boring as a winter morning"!
先行スペースに注意してください。これはより複雑なパターンで解決できます。line=${line//\?*([[:blank:]])/$'"?\n'}
私は以下を使用しますsed
:
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
new=$( sed 's/[?!][[:blank:]]*/&\n/g' <<<"$line" )
echo "$new"
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
アッsplit()
区切り文字をキャプチャする機能がありますが、それを使用するのは非常に冗長です。
echo "$line" | awk '{
n = split($0, words, /[!?][[:blank:]]*/, seps)
for (i = 1; i < n; i++)
print words[i] seps[i]
print words[n]}
'