提问人:ak1234 提问时间:11/16/2023 更新时间:11/17/2023 访问量:94
删除第一个和最后一个双引号(最好是 sed/awk)
Removing first and last double quote (preferably sed/awk)
问:
我只想删除第一个和最后一个双引号
输入:
word1 -word2 {word3} -word4 {"word5 'word6' "word7 word8" .word9"} -word10 (word11)
word1 -word2 {word3} -word4 {"word5 'word6' word7 word8 .word9"} -word10 (word11)
word1 -word2 {word3} -word4 {"word5 'word6' "word7 (word8)" .word9"} -word10 (word11)
预期输出:
word1 -word2 {word3} -word4 {word5 'word6' "word7 word8" .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' word7 word8 .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' "word7 (word8)" .word9} -word10 (word11)
尝试删除第一个“ 但不起作用
sed 's/"\({\)/\1/g' inputfile > outputfile
删除行中的第一个双引号,即可以接受“{”之后和“}”之前。
假设单词的长度也可以不同。
答:
3赞
anubhava
11/16/2023
#1
您可以将此 sed 与捕获组一起使用:
sed -E 's/\{"(.*)"}/{\1}/' file
word1 -word2 {word3} -word4 {word5 'word6' "word7 word8" .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' word7 word8 .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' "word7 (word8)" .word9} -word10 (word11)
这里的模式匹配 和 之间的最长匹配,并将中间的捕获测试捕获到捕获组中。{"(.*)"}
{"
"}
评论
1赞
Ed Morton
11/16/2023
FWIW 你不需要转义 .}
0赞
anubhava
11/16/2023
}
仍然被认为是正则表达式元字符。如果我调用 Python,它会给出:即两者都转义了。re.escape('{}')
\{\}
0赞
Ed Morton
11/16/2023
不是在您正在使用的 ERE 中 - 如果它之前有一个 RE 间隔打开,则只是一个 metachar,就像跟随与否一样。在 POSIX 中,在任何其他上下文中都是未定义的行为(就像几乎任何其他字符一样),但我希望通常会被视为字面意思,因此可能不会真正造成任何伤害。也许 python 假设 PCRE?我不知道PCRE规则是什么。}
{
)
(
\}
\
1赞
Ed Morton
11/16/2023
现在看看 pubs.opengroup.org/onlinepubs/9699919799/basedefs/......它说:“一个普通的角色是一个与自己相匹配的 ERE。普通字符是受支持的字符集中的任何字符,但 ERE 特殊字符中列出的 ERE 特殊字符除外。以未转义的<反斜杠> ( '\\' ) 开头的普通字符的解释是未定义的,除非在括号表达式的上下文中”。因此,是一个普通字符,因此在这种情况下的解释是不确定的。}
\}
1赞
anubhava
11/17/2023
谈论PCRE回报preg_quote('/}/')
/\}/
2赞
RavinderSingh13
11/16/2023
#2
第1种解决方案:对于您展示的示例,请尝试以下 GNU 代码。使用函数,其中使用正则表达式创建 3 个捕获组并将其值保存到名为 arr 的数组中,如果找到真正的匹配项,则只需打印数组的所有值即可获得所需的输出。awk
match
(^.*{)"(.*)"(}.*$)
awk 'match($0,/(^.*{)"(.*)"(}.*$)/,arr){print arr[1] arr[2] arr[3]}' Input_file
这是使用正则表达式的在线演示。
第二种解决方案:或者,如果您的数据与所示样本相同,并且每行仅出现 1 次,则尝试以下操作。{"
"}
awk '{sub(/{"/,"{");sub(/"}/,"}")} 1' Input_file
1赞
Daweo
11/17/2023
#3
我会利用 GNU 来完成这个任务,让内容成为AWK
file.txt
word1 -word2 {word3} -word4 {"word5 'word6' "word7 word8" .word9"} -word10 (word11)
word1 -word2 {word3} -word4 {"word5 'word6' word7 word8 .word9"} -word10 (word11)
word1 -word2 {word3} -word4 {"word5 'word6' "word7 (word8)" .word9"} -word10 (word11)
然后
awk 'BEGIN{FPAT="\"|[^\"]*";OFS=""}{$2=$(NF-1)="";print}' file.txt
给出输出
word1 -word2 {word3} -word4 {word5 'word6' "word7 word8" .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' word7 word8 .word9} -word10 (word11)
word1 -word2 {word3} -word4 {word5 'word6' "word7 (word8)" .word9} -word10 (word11)
解释:我告诉 GNU,字段要么是单个的,要么是零或多个非的,输出中的字段之间不应该添加任何内容。然后,对于每一行,我将第二个字段(第一个)和最后一个字段(最后一个)之前的字段设置为空字符串,即删除它。免责声明:此解决方案假定从来都不是第一行的最后一个字符,也绝不是最后一行的字符。AWK
"
"
"
"
"
"
(在 GNU Awk 5.1.0 中测试)
评论
sed 's/"\(.*\)"/\1/'
"
{
}
/"\({\)/
"
{
{
"