IFS=$'?\n'
for line in $(cat "./newfiletoread")
do printf "${line}\n"
done
文件内容如下: 你好!你好吗?生活怎么样?我的生活就像冬天的早晨一样无聊!
上面的代码在遇到“?”时分割文件的内容或者 '!'或者'/n',这很好。但是,在扩展过程中,shell 会从文件中删除这些字符。以下是我得到的输出。
Hello there
How are you doing
How is life
Mine is as boring as a winter morning
我知道 shell 的工作原理是在命令执行之前用空格替换这些 IFS 值。有没有办法在分割过程中保留这些分隔符?我想得到像下面这样的输出:
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
答案1
第一的,不要读取文件的行for
我在某处读到过关于分割字符串的内容:split
当你知道要扔掉什么时使用;当您知道要保留什么时,请使用正则表达式。或类似的东西。
使用 shell 分词的问题$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!
awk有一个split()
函数可以让你捕获分隔符,但使用它非常冗长:
echo "$line" | awk '{
n = split($0, words, /[!?][[:blank:]]*/, seps)
for (i = 1; i < n; i++)
print words[i] seps[i]
print words[n]}
'