将句子拆分成单独的行
Split sentences into separate lines
我正在尝试使用 shell 脚本将文件中的句子拆分成单独的行。
现在我想用 !, ? 分割字符串要么 。 .输出应该是这样的:
我想从 my_text.txt 中读取并包含
的文件
you want to learn shell script? First, you want to learn Linux command! then. you can learn shell script.
现在我想用“!”或“?”或“.”拆分字符串。输出应该是这样的:
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
我用过这个脚本:
while read p
do
echo $p | tr "? ! ." "\n "
done < my_text.txt
但输出是:
you want to learn shell script
First, you want to learn Linux command then you can learn shell script
有人可以帮忙吗?
Awk 非常适合这个:
awk -F '[?.!]' '{ for (i=1;i<=NF;i++) { print $i } }' file
将字段分隔符设置为?要么 。要么 !然后遍历每个字段并打印条目。
您可以调用 3 个 tr 命令拆分 ? !和.
cat test_string.txt | tr "!" "\n" | tr "?" "\n" | tr "." "\n"
这可以在单个 awk
中使用其全局替换选项完成,如下所示,仅在 GNU awk
中使用所示示例编写和测试。只需全局替换 ?
、!
、.
为新行(默认情况下 ORS
(输出记录分隔符)值作为新行)。
awk '{gsub(/\?|!|\./,ORS)} 1' Input_file
那不是您使用 tr
的方式。它的两个参数的长度应该相同,否则第二个参数将通过重复其最后一个字符 * 扩展到第一个的长度——也就是说,在这种情况下,一个 space—使逐一音译成为可能。换句话说,给定 ? ! .
和 \n
作为参数,tr
将用换行符替换 ?
,而 !
、
和.
与 space。我猜你要找的是:
$ tr '?!.' '\n' <file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
或者,更方便地说:
tr '?!.' '[\n*]' <file
*这就是 GNU tr
所做的,POSIX 在参数长度不同时未指定行为。
在gnu-awk
中我们可以用gensub()
函数得到:
awk '{print gensub(/([.?!]\s*)/, "\n", "g", [=10=])}' file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
$ sed 's/[!?.]/\n/g' file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
为什么要将自己限制在新行\n 作为 RS?也许是这样的:
- \056 是句点。 \040 是 space。如果有,我会添加 +
是在每个句子和 u 之后键入 2 spaces 的传统做法
想要标准化它。
- 我假设问号 \044 更频繁
而不是感叹\041。我使用全八进制的唯一原因是
所有这些都是可以在终端上破坏 havor 的东西
没有正确引用和转义的可能性很小。
- 与 FS 或 RS 不同,OFS/ORS 是常量字符串(是吗?),因此输入字符是安全的。
- 经期由 RS 负责。无需特殊处理。那么,如果该行两者都不包含?也不! ,按原样打印,然后继续(它将处理 ".\n" )
.
mawk 'BEGIN { RS = "[6][0]+" ; ORS = ". \n";
FS = "[4][0]+"; OFS = "? \n"; }
([=10=] !~ /[14]/) {
print; next; }
/[1]/ {
gsub("[1][0]+", "1 \n"); }
( NF==1 ) || ( = )'
和 mawk 一样快,gsub ( ) 或 $1=$1 仍然要花钱,所以跳过昂贵的部分,除非它实际上有一个 ?要么 !马克.
最后一行是有趣的技巧,*在大括号之外完成。你已经完成了!之前的那一行,所以如果没有?找到(又名 NF 为 1),然后那个评估为真,awk 将短路并且不执行第 2 部分,只需打印。
但是如果你找到了?标记, $1=$1 的赋值将以新的顺序重新排列它们,并且因为它是一个赋值操作而不是相等比较,如果赋值本身没有失败,它总是返回成功,这也将作为它自己的始终-true 标志打印到最后。
Awk 的记录分隔符变量 RS
应该可以解决问题。
echo 'you want to learn shell script? First, you want to learn Linux command! then. you can learn shell script.' |
awk 'BEGIN{RS="[?.!] "}1'
我正在尝试使用 shell 脚本将文件中的句子拆分成单独的行。
现在我想用 !, ? 分割字符串要么 。 .输出应该是这样的:
我想从 my_text.txt 中读取并包含
的文件you want to learn shell script? First, you want to learn Linux command! then. you can learn shell script.
现在我想用“!”或“?”或“.”拆分字符串。输出应该是这样的:
you want to learn shell script First, you want to learn Linux command then you can learn shell script
我用过这个脚本:
while read p
do
echo $p | tr "? ! ." "\n "
done < my_text.txt
但输出是:
you want to learn shell script
First, you want to learn Linux command then you can learn shell script
有人可以帮忙吗?
Awk 非常适合这个:
awk -F '[?.!]' '{ for (i=1;i<=NF;i++) { print $i } }' file
将字段分隔符设置为?要么 。要么 !然后遍历每个字段并打印条目。
您可以调用 3 个 tr 命令拆分 ? !和.
cat test_string.txt | tr "!" "\n" | tr "?" "\n" | tr "." "\n"
这可以在单个 awk
中使用其全局替换选项完成,如下所示,仅在 GNU awk
中使用所示示例编写和测试。只需全局替换 ?
、!
、.
为新行(默认情况下 ORS
(输出记录分隔符)值作为新行)。
awk '{gsub(/\?|!|\./,ORS)} 1' Input_file
那不是您使用 tr
的方式。它的两个参数的长度应该相同,否则第二个参数将通过重复其最后一个字符 * 扩展到第一个的长度——也就是说,在这种情况下,一个 space—使逐一音译成为可能。换句话说,给定 ? ! .
和 \n
作为参数,tr
将用换行符替换 ?
,而 !
、
和.
与 space。我猜你要找的是:
$ tr '?!.' '\n' <file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
或者,更方便地说:
tr '?!.' '[\n*]' <file
*这就是 GNU tr
所做的,POSIX 在参数长度不同时未指定行为。
在gnu-awk
中我们可以用gensub()
函数得到:
awk '{print gensub(/([.?!]\s*)/, "\n", "g", [=10=])}' file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
$ sed 's/[!?.]/\n/g' file
you want to learn shell script
First, you want to learn Linux command
then
you can learn shell script
为什么要将自己限制在新行\n 作为 RS?也许是这样的:
- \056 是句点。 \040 是 space。如果有,我会添加 + 是在每个句子和 u 之后键入 2 spaces 的传统做法 想要标准化它。
- 我假设问号 \044 更频繁 而不是感叹\041。我使用全八进制的唯一原因是 所有这些都是可以在终端上破坏 havor 的东西 没有正确引用和转义的可能性很小。
- 与 FS 或 RS 不同,OFS/ORS 是常量字符串(是吗?),因此输入字符是安全的。
- 经期由 RS 负责。无需特殊处理。那么,如果该行两者都不包含?也不! ,按原样打印,然后继续(它将处理 ".\n" )
.
mawk 'BEGIN { RS = "[6][0]+" ; ORS = ". \n";
FS = "[4][0]+"; OFS = "? \n"; }
([=10=] !~ /[14]/) {
print; next; }
/[1]/ {
gsub("[1][0]+", "1 \n"); }
( NF==1 ) || ( = )'
和 mawk 一样快,gsub ( ) 或 $1=$1 仍然要花钱,所以跳过昂贵的部分,除非它实际上有一个 ?要么 !马克.
最后一行是有趣的技巧,*在大括号之外完成。你已经完成了!之前的那一行,所以如果没有?找到(又名 NF 为 1),然后那个评估为真,awk 将短路并且不执行第 2 部分,只需打印。
但是如果你找到了?标记, $1=$1 的赋值将以新的顺序重新排列它们,并且因为它是一个赋值操作而不是相等比较,如果赋值本身没有失败,它总是返回成功,这也将作为它自己的始终-true 标志打印到最后。
Awk 的记录分隔符变量 RS
应该可以解决问题。
echo 'you want to learn shell script? First, you want to learn Linux command! then. you can learn shell script.' |
awk 'BEGIN{RS="[?.!] "}1'