我在Ubuntu20.04中使用Bash。
我有档案:
Hello hi 123
if a equals b
you
one abc two three four
dany uri four 123我只需要在sed中找到--只有4个单词的行。这是我编写的代码,它不工作,它准确地打印文件。
sed "/[a-Z0-9+]{4}/g" F1发布于 2021-01-01 14:02:27
这个问题应该通过一个容易计算字段的工具来解决,比如awk:
$ awk 'NF == 4' file
if a equals b
dany uri four 123它使用NF,这是awk中的一个特殊变量,它将保存当前记录中的字段数。默认情况下,记录是一行,字段将是由一个或多个空白字符(制表符或空格)分隔的任何子字符串,不包括行首或行尾的空字段。上述简短的awk程序将输出任何一行,正好有四个字段。
对于sed,您需要匹配空格分隔的子字符串。
注意,默认情况下,sed使用基本正则表达式,而您显示的表达式使用{4},这是一个扩展的正则表达式修饰符。基本正则表达式中的等效内容将是编写\{4\}。您还使用了无效的字符范围a-Z,并且您打算使用的字符类最好写成[[:alnum:]],也就是匹配任何字母数字字符的东西(假设包含+是一个错误)。后面的g命令(从“持有空间”获取数据)似乎放错了位置。
我在这里的一般想法是将每个单词(运行一个或多个非空白字符)压缩为单个x,然后删除所有空白字符(制表符或空格)。如果得到的字符串恰好是xxxx,则打印原始行(否则删除该行并立即启动下一个循环)。
sed -e h \
-e 's/[^[:blank:]]\{1,\}/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file在这里,原始行首先用h保存到“持有空间”,然后在需要打印时再取回来,最后是g。如果执行倒数第二行上的d命令,则永远不会考虑最终的g。
或者,使用扩展正则表达式:
sed -E -e h \
-e 's/[^[:blank:]]+/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file测试:
$ sed -e h \
> -e 's/[^[:blank:]]\{1,\}/x/g' \
> -e 's/[^x]//g' \
> -e '/^xxxx$/!d' \
> -e g file
if a equals b
dany uri four 123如果您希望由[[:alnum:]]类而不是由[^[:blank:]] (非空白)定义单词字符,那么在上面的表达式中将[^[:blank:]]更改为[[:alnum:]]。不同之处在于,字符串(如GNU/Linux或Unix-system )将被计算为两个单词,而不是每个单词。
发布于 2021-01-01 13:52:32
使用GNU sed:
$ sed -E '/^\s*(\w+\s+){3}\w+\s*$/!d' infile
if a equals b
dany uri four 123POSIXly;您可以写:
sed '/^[[:space:]]*\([_[:alnum:]][_[:alnum:]]*[[:space:]][[:space:]]*\)\{3\}[_[:alnum:]][_[:alnum:]]*[[:space:]]*$/!d' infile发布于 2021-01-01 16:54:55
用bash边读边读:
set -o noglob
while IFS= read -r line
do
set -- $line
[ $# -eq 4 ] && echo "$line"
done < file$#:参数数。
https://unix.stackexchange.com/questions/627086
复制相似问题