我正在努力实现以下目标:
有一个包含多个单词的文件,例如:
示例txt的输出为
testStr
testmystring
testmystring_1
testmystringwq
testStr_3
testStrasd
testStr-345
testStr1
testingStr1
现在我要实现的是,如果我逐行操作文件,即第一次使用testStr,那么应该删除所有从testStr开头的单词,但在这里应该保留testStr。
预期输出为
testStr
testmystring
testmystring_1
testmystringwq
testingStr1
现在应该比较文件中的下一个字符串,即testmystring。然后预期的输出是
testStr
testmystring
testingStr1
依此类推...
我尝试使用sed命令通过模式进行删除,并且可以正常工作。但是我需要将原始模式保留在文件中。
sed -i '/testStr*/d' ./sample txt
答案 0 :(得分:1)
这可能对您有用(GNU sed):
sed 's/\<\(testStr\)\S*/\1/;H;$!d;x;s/.//;:a;s/\<\(\(testStr\n\).*\)\2/\1/;ta' file
删除字符串testStr
之后的所有字符。将结果和不变的行存储在保留空间中。在文件末尾,删除引入的换行符,然后删除字符串testStr
以外的所有字符串。
一个更简单的解决方案可能是:
sed 's/\<\(testStr\)\S*/\1/' file | sort -u
但是,这将删除除testStr
以外的其他行的重复项,并且还可能更改原始顺序。
编辑:为了适应对原始问题的更改,提供了两个文件。第一个原始文件包含要测试的字符串(file),新的第二个文件仅包含要匹配的字符串(fileInput)。
使用上述解决方案和替代方法,从fileInput构建脚本:
sed 'H;$!d;x;s/.//;s/\n/|/g;s#.*#s/\\<(&)\\S*/\\1/;H;$!d;x;s/.//;:a;s/\\<(((&)\\n).*)\\2/\\1/;ta#' fileInput |
sed -Ef - file
答案 1 :(得分:0)
那呢?
$ grep -Evf <(sed 's/^/^/; s/$/.+/' sample.txt) sample.txt
testStr
testmystring
testingStr1
(需要bash,zsh,ksh93或其他能够理解<(command)
样式重定向的shell。)
答案 2 :(得分:0)
这是如何使用文字字符串执行的操作:
$ awk 'NR==FNR{tgts[$0]; next} {for (tgt in tgts) if (($0 != tgt) && (index($0,tgt) == 1)) next} 1' targets file
testStr
testmystring
testingStr1
以上内容在这些输入文件上运行:
$ tail -n +0 targets file
==> targets <==
testStr
testmystring
==> file <==
testStr
testmystring
testmystring_1
testmystringwq
testStr_3
testStrasd
testStr-345
testStr1
testingStr1
无论哪个文件中包含什么字符,以上内容都将起作用。