Awk 删除一行,然后删除最后一行的逗号和匹配的模式
我的目标是删除数据库中的所有约束,因此我希望用简单的代码搜索单词“CONSTRAINT”并删除该行 我试着用sedAwk 删除一行,然后删除最后一行的逗号和匹配的模式,awk,sed,Awk,Sed,我的目标是删除数据库中的所有约束,因此我希望用简单的代码搜索单词“CONSTRAINT”并删除该行 我试着用sed DROP TABLE IF EXISTS `qalnk`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `qalnk` ( `id` bigint(20) NOT NULL, `
DROP TABLE IF EXISTS `qalnk`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `qalnk` (
`id` bigint(20) NOT NULL,
`answer_id` bigint(20) DEFAULT NULL,
`date_deleted` bigint(20) DEFAULT NULL,
`deleted_by_user_ap_id` varchar(36) DEFAULT NULL,
`expression_id` bigint(20) DEFAULT NULL,
`expression_type` varchar(255) DEFAULT NULL,
`ordering` int(11) DEFAULT NULL,
`question_id` bigint(20) DEFAULT NULL,
`expression_for_deselect_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK6661B19F393DFCD` (`expression_id`),
KEY `FK6661B195182DDCD` (`question_id`),
KEY `FK6661B195742A56B` (`expression_for_deselect_id`),
KEY `idx_qlnk_nswrd` (`answer_id`),
KEY `FK6661B19126D878D` (`answer_id`),
KEY `FK6661B1975B33071` (`id`),
CONSTRAINT `FK6661B19126D878D` FOREIGN KEY (`answer_id`) REFERENCES `ans` (`id`),
CONSTRAINT `FK6661B1975B33071` FOREIGN KEY (`id`) REFERENCES `apobj` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
但是,由于约束是最后一条语句,所以所有这些尾随逗号都被抛在了后面。我不介意它是awk、sed还是一些常用工具
所需输出为
sed '/\s*CONSTRAINT/d' ~/Downloads/dump.sql > ~/ouput.sql
使用(GNU)
awk
将尾随的,
s移动到后续行的开头,然后执行sed
删除,这有点像黑客
DROP TABLE IF EXISTS `qalnk`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `qalnk` (
`id` bigint(20) NOT NULL,
`answer_id` bigint(20) DEFAULT NULL,
`date_deleted` bigint(20) DEFAULT NULL,
`deleted_by_user_ap_id` varchar(36) DEFAULT NULL,
`expression_id` bigint(20) DEFAULT NULL,
`expression_type` varchar(255) DEFAULT NULL,
`ordering` int(11) DEFAULT NULL,
`question_id` bigint(20) DEFAULT NULL,
`expression_for_deselect_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK6661B19F393DFCD` (`expression_id`),
KEY `FK6661B195182DDCD` (`question_id`),
KEY `FK6661B195742A56B` (`expression_for_deselect_id`),
KEY `idx_qlnk_nswrd` (`answer_id`),
KEY `FK6661B19126D878D` (`answer_id`),
KEY `FK6661B1975B33071` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
这给了我以下信息,它们应该是有效的SQL
awk -v RS= '{gsub(/,\n/, "\n,"); print}' ~/Downloads/dump.sql |
sed '/\s*CONSTRAINT/d' > ~/ouput.sql
使用(GNU)
awk
将尾随的,
s移动到后续行的开头,然后执行sed
删除,这有点像黑客
DROP TABLE IF EXISTS `qalnk`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `qalnk` (
`id` bigint(20) NOT NULL,
`answer_id` bigint(20) DEFAULT NULL,
`date_deleted` bigint(20) DEFAULT NULL,
`deleted_by_user_ap_id` varchar(36) DEFAULT NULL,
`expression_id` bigint(20) DEFAULT NULL,
`expression_type` varchar(255) DEFAULT NULL,
`ordering` int(11) DEFAULT NULL,
`question_id` bigint(20) DEFAULT NULL,
`expression_for_deselect_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK6661B19F393DFCD` (`expression_id`),
KEY `FK6661B195182DDCD` (`question_id`),
KEY `FK6661B195742A56B` (`expression_for_deselect_id`),
KEY `idx_qlnk_nswrd` (`answer_id`),
KEY `FK6661B19126D878D` (`answer_id`),
KEY `FK6661B1975B33071` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
这给了我以下信息,它们应该是有效的SQL
awk -v RS= '{gsub(/,\n/, "\n,"); print}' ~/Downloads/dump.sql |
sed '/\s*CONSTRAINT/d' > ~/ouput.sql
尽管有反对票,我认为这个答案提供了有效的解决方案,正如广告所宣传的那样,同时(希望)也能提供信息。如果不是,请务必告诉我们,以便我可以修复它。
单程sed
解决方案要求同时读取所有输入行,类似于:
AGNUsed
解决方案:
DROP TABLE IF EXISTS `qalnk`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `qalnk` (
`id` bigint(20) NOT NULL
, `answer_id` bigint(20) DEFAULT NULL
, `date_deleted` bigint(20) DEFAULT NULL
, `deleted_by_user_ap_id` varchar(36) DEFAULT NULL
, `expression_id` bigint(20) DEFAULT NULL
, `expression_type` varchar(255) DEFAULT NULL
, `ordering` int(11) DEFAULT NULL
, `question_id` bigint(20) DEFAULT NULL
, `expression_for_deselect_id` bigint(20) DEFAULT NULL
, PRIMARY KEY (`id`)
, KEY `FK6661B19F393DFCD` (`expression_id`)
, KEY `FK6661B195182DDCD` (`question_id`)
, KEY `FK6661B195742A56B` (`expression_for_deselect_id`)
, KEY `idx_qlnk_nswrd` (`answer_id`)
, KEY `FK6661B19126D878D` (`answer_id`)
, KEY `FK6661B1975B33071` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
使用NUL(空字节)作为输入行分隔符,由于在输入中没有嵌入NUL,因此-z
文件的全部内容将立即读入模式空间
启用扩展正则表达式(现代语法、扩展功能)-r
- 正则表达式将删除前一行中的所有
行,包括约束
,从而使包含的,\n
语句的语法保持不变CREATE TABLE
sed
解决方案要麻烦得多:
BSDsed
版本缺少GNU的许多(非标准)便利功能,这使得解决方案更加痛苦。
BSDsed
只提供了对POSIX标准的一些扩展,但一个值得注意的是能够使用所谓的扩展正则表达式
sed -zr 's/,\n\s*CONSTRAINT\s+[^\n,]+//g' file
-类似于GNU-E
的sed
-启用扩展正则表达式-r
sed -zr 's/,\n\s*CONSTRAINT\s+[^\n,]+//g' file
:a\n$!{N;b\na}
是一种常见的sed
习惯用法,它一次读取整个输入:
:定义要跳转到的标签
$代码>匹配每一行,但(
)最后一行(!
)$
将下一行读入模式空间(要操作的输入缓冲区),然后分支({N;ba}
)到标签b
(a
):a
- 换句话说:这会将所有行读入模式空间,随后的命令将对其进行操作(
,在本例中)s
- 通过使用多个
选项,可以将其塞进一行,但这会降低命令的可读性-e
[[:blank:]
,因为不支持快捷方式类,如\s
。
- 特别是,虽然原则上可以在正则表达式中匹配
,但无法在字符类中识别它。因此,\n
必须与[^\n]
进行模拟--[:print:][:blank:][:blank:][]
[:blank:][/code>被添加为也匹配制表符,这些制表符不被视为可打印字符;(
也不能在char.class内使用)\t
sed
解决方案要求同时读取所有输入行,类似于:
AGNUsed
解决方案:
DROP TABLE IF EXISTS `qalnk`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `qalnk` (
`id` bigint(20) NOT NULL
, `answer_id` bigint(20) DEFAULT NULL
, `date_deleted` bigint(20) DEFAULT NULL
, `deleted_by_user_ap_id` varchar(36) DEFAULT NULL
, `expression_id` bigint(20) DEFAULT NULL
, `expression_type` varchar(255) DEFAULT NULL
, `ordering` int(11) DEFAULT NULL
, `question_id` bigint(20) DEFAULT NULL
, `expression_for_deselect_id` bigint(20) DEFAULT NULL
, PRIMARY KEY (`id`)
, KEY `FK6661B19F393DFCD` (`expression_id`)
, KEY `FK6661B195182DDCD` (`question_id`)
, KEY `FK6661B195742A56B` (`expression_for_deselect_id`)
, KEY `idx_qlnk_nswrd` (`answer_id`)
, KEY `FK6661B19126D878D` (`answer_id`)
, KEY `FK6661B1975B33071` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
使用NUL(空字节)作为输入行分隔符,由于在输入中没有嵌入NUL,因此-z
文件的全部内容将立即读入模式空间
启用扩展正则表达式(现代语法、扩展功能)-r
- 正则表达式将删除前一行中的所有
行,包括约束
,从而使包含的,\n
语句的语法保持不变CREATE TABLE
sed
解决方案要麻烦得多:
BSDsed
版本缺少GNU的许多(非标准)便利功能,这使得解决方案更加痛苦。
BSDsed
只提供了对POSIX标准的一些扩展,但一个值得注意的是能够使用所谓的扩展正则表达式
sed -zr 's/,\n\s*CONSTRAINT\s+[^\n,]+//g' file
-类似于GNU-E
的sed
-启用扩展正则表达式-r
sed -zr 's/,\n\s*CONSTRAINT\s+[^\n,]+//g' file
:a\n$!{N;b\na}
是一种常见的sed
习惯用法,它一次读取整个输入:
:定义要跳转到的标签
$代码>匹配每一行,但(
)最后一行(!
)$
将下一行读入模式空间(要操作的输入缓冲区),然后分支({N;ba}
)到标签b
(a
):a
- 换句话说:这会将所有行读入模式空间,随后的命令将对其进行操作(
,在本例中)s