【问题标题】:Reading from A to B, but stop at the first occurrence of B从 A 读取到 B,但在第一次出现 B 时停止
【发布时间】:2016-06-04 01:16:24
【问题描述】:

我正在尝试做一个 shell 脚本,它从文件中读取字符串 A 到 B 字符串。字符串 A 我确定是 UNIQUE,但是字符串 B 重复了不止一次。

我正在读取包含大量 CREATE 查询的文件。

每个查询都以 (my String B) 结尾

); ------------------------

字符串 A 是这样组成的:

CREATE MULTISET TABLE DBNAME.TABLENAME

所以我用 sed 从 A 读到 B

sed -n "/$FROMSTR/,/$TOSTR/p" $2 >> querytest.txt

我想停在$TOSTR (String B) 的第一次出现

【问题讨论】:

  • 问题是……?如果 A 是唯一的,那么您所拥有的将在 A 之后的第一个 B 处停止。
  • @JonathanLeffler, ...停止打印,但不一定停止阅读。如果停止点是 2GB 文件中的 5K,则差异可能很大。

标签: string bash shell


【解决方案1】:

代替:

sed -n "/$FROMSTR/,/$TOSTR/p"

使用:

sed -n "/$FROMSTR/,\${p; /$TOSTR/q}"

这会从$FROMSTR 的第一次出现打印到最后一行$,除非它在看到$TOSTR 的第一次出现时退出。

除此之外:您应该确保您信任FROMSTRTOSTR 的来源。如果任一变量包含 sed-active 字符,则结果可能不是您想要的。

示例 1

举个简单的例子:

$ FROMSTR=2; TOSTR=4; seq 10 | sed -n "/$FROMSTR/,\${p; /$TOSTR/q}"
2
3
4

示例 2

作为更接近您的实际输入的示例,请考虑以下测试文件:

$ cat file
1
CREATE MULTISET TABLE DBNAME.TABLENAME
2
3
); ------------------------
4

然后运行这个命令:

$ FROMSTR="CREATE MULTISET TABLE DBNAME.TABLENAME"
$ TOSTR="); ------------------------"
$ sed -n "/$FROMSTR/,\${p; /$TOSTR/q}" file
CREATE MULTISET TABLE DBNAME.TABLENAME
2
3
); ------------------------

示例 3

考虑这个测试文件:

$ cat file
1
CREATE MULTISET TABLE DBNAME.TABLENAME
2
); ------------------------
); ------------------------
3
CREATE MULTISET TABLE DBNAME.TABLENAME
4
); ------------------------
5

我们定义我们的变量:

$ FROMSTR="CREATE MULTISET TABLE DBNAME.TABLENAME"
$ TOSTR="); ------------------------"

然后,运行我们的代码:

$ sed -n "/$FROMSTR/,\${p; /$TOSTR/q}" file
CREATE MULTISET TABLE DBNAME.TABLENAME
2
); ------------------------

【讨论】:

  • 您希望$p 扩展到什么?
  • @amphetamachine 好点。这在更新中被消除了。
  • @John1024 它一直在打印所有出现的地方,但仍然缺少一些东西:/
  • @MartinMcFlyDeLuca 我刚刚尝试了一个更复杂的示例文件(请参阅更新答案中的“示例 3”)。我仍然显示它打印 only 第一次出现。 q 命令导致sed$FROMSTR 第一次出现后到达$TOSTR 的第一次出现时退出。请为我尝试示例 3,如果您发现任何不同之处,请告诉我。
  • @John1024 第一个例子不可能发生,我确定该文件是作为创建语句然后);----- 等等
【解决方案2】:

我的问题解决了,看来sed在管理转义字符方面有问题(\r\n)

我将 $TOSTR 更改为 ");"

并使用了循环。

sed -n "/$FROMSTR/{p; :loop n; p; /$TOSTR/q; b loop}" $2 >> $3

然后我在“);”之后回显我需要的字符

echo -e "\r\n--------------------------------------------------------------------------------" >> $3

An useful one on stackoverflow that explain loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 2020-11-20
    相关资源
    最近更新 更多