2017-10-14 114 views
2

我看过这篇文章:sed delete remaining characters in line except first 5它帮助我删除x后的所有字符。但是,我很难找到如何删除x字符后的所有单词。如何删除X字符后的所有单词

我开始使用此代码:

echo "StackOverflow Users Are Brilliant And Hard Working" | sed 's/.//30g' 
#character 30 ---------------------^ 

我尝试:

echo "StackOverflow Users Are Brilliant And Hard Working" | sed 's/ .* //30g' 
#character 30 ---------------------^ 

在这些输出,我要么切断了最后一个字或词计数。相反,我需要删除30个字符后的单词。我在不同的行/字长度上运行它,这就是为什么我不能把它放在单词的末尾。

所需的输出:

StackOverflow Users Are Brilliant 

如果你知道如何放在一起计算后x个字的话,您的帮助将不胜感激。

请注意:如前所述,不要将代码更改为33或34个字符。问题的关键在于在30个字符后删除所有单词。

回答

2

AWK会做

$ awk 'BEGIN{FS=OFS="" } length>30{i=30; while($i~/\w/) i++; NF=i-1; }1' file 
StackOverflow Users Are Brilliant 
This line has 22 chars 

设置FS=OFS=""使每一个字符被认为是场

如果length>30然后i=30; while($i~/\w/) i++;即不断递增i,直到我们降落在一个非alnum字符;一旦循环结束设置所需的NF

length<=30一致的行将被打印。

使用的grep

$ grep -oE "^.{1,29}\w*" file 
StackOverflow Users Are Brilliant 
This line has 22 chars 

^.{1,29}\w*129因为如果30th焦炭是非alnum那么它不应该被考虑。

+1

酷解决方案@batman :-)适用于我! – DomainsFeatured

+0

grep解决方案是最短的一个,我试图用grep解决这个问题,但忘记了'^'并且它产生了多行。 –

+0

@Paweł[email protected],我实际上在我的程序中使用了Pawel的解决方案。但是,我选择这个是因为'awk'和'grep'的双重回答。此外,它的得分最高,我确实欠你一个蝙蝠侠。帕维尔,我希望很多人都喜欢你的答案,因为你给出了非常有帮助的解释。它对我帮助很大,也会帮助其他人。再次感谢batMan :-) – DomainsFeatured

2

怎么样简单的和清醒的awk与它的神奇效用SUBSTR:

echo "StackOverflow Users Are Brilliant And Hard Working" | awk '{print substr($0,1,34)}' 

如果你想传递长度的awk然后以下可能会帮助你一样。

echo "StackOverflow Users Are Brilliant And Hard Working" | awk -v end=34 '{print substr($0,1,end)}' 

如果你希望你的长度保存在一个shell变量,并希望通过它的awk然后以下可能会帮助你一样。

val="34" 
echo "StackOverflow Users Are Brilliant And Hard Working" | awk -v var="$val" '{print substr($0,1,var)}' 

编辑:添加上相同的一个SED解决方案了。

echo "StackOverflow Users Are Brilliant And Hard Working" | sed 's/\(.\{34\}\)\(.*\)/\1/' 
+1

@DomainsFeatured,您的欢迎。看到我的编辑添加了3种方法(包括sed)来解决这个问题,让我知道如果有任何疑问相同。 – RavinderSingh13

+1

哦,废话,我只是意识到这是行不通的!我需要它在30个字符上工作,而不是34 :-(输出是:'StackOverflow用户是Brilli' – DomainsFeatured

+0

@DomainsFeatured,我已经给出了34个字符的解决方案,因为我已经看到了您的预期输出(直到辉煌的单词) ,显然你可以根据你的需要调整角色。 – RavinderSingh13

1

你可以用SED做到这一点:

echo "StackOverflow Users Are Brilliant And Hard Working" | sed 's/\(.\{1,30\}\w*\)\(.*\)/\1/' 

这应该适用于文本少于30个字符,以及 - 没有修剪发生在这种情况下。

说明

这是我开始用正则表达式:

.{1,30}\w* 

它只是获取1-30个字符,然后将所有的附加词字符之后的。

我们能够在sed我们不得不去掉一切使用它,我们需要两组:

(.{1,30}\w*)(.*) 

现在,一些逃脱的“()”和“{}”:

\(.\{1,30\}\w*\)\(.*\) 

这可以去的sed:

sed 's/<pattern>/<replacement>/<flags>' 

我们要删除第二组,这样在sed我们使用 '\ 1'(第一组)更换:

echo "..." | sed 's/\(.\{1,30\}\w*\)\(.*\)/\1/' 
+0

嘿帕维尔,是的!这是我正在寻找的。如果您可以提供'\(。\ {1,30 \} \ w \ + \)\(。* \)/ \ 1'部分的解释,我很乐意学习。否则,感谢您的帮助。我会在今天晚些时候标记最好的答案:-) – DomainsFeatured

+0

有一个小错误,我编辑了答案。我会在几分钟内写出解释。 –

+1

说明已添加 –

1

这可能为你工作(GNU SED):

sed -r 's/^(.{30}\S*).*/\1/' file 

这保留了前30个字符和任何以下非空格字符。

N.B.如果30字符是一个空格,下面的字将被包括在内,所以正则表达式可能是:

sed -r 's/^(.{29}\S*).*/\1/' file 
+0

嘿@potong,非常感谢你的回答和解释。这使得很多道理:-) – DomainsFeatured

1

使用bash

var="StackOverflow Users Are Brilliant And Hard Working" 
echo ${var:0:30} 

或者

expr substr "$var" 1 30 
+0

不适合我...我得到的输出:'StackOverflow用户是Brilli' – DomainsFeatured

+0

对不起,我明白你想停止30个字符后 –

+0

是的,但我需要包括其余的单词'StackOverflow用户是辉煌的'。您的输出将'Brilliant'剪切成'Brilli' – DomainsFeatured

0

随着GNU AWK的gensub():

$ awk '{$0=gensub(/(.{30}\S*).*/,"\\1",1)} 1' file 
StackOverflow Users Are Brilliant 

或GNU sed的:

$ sed -E 's/(.{30}\S*).*/\1/' file 
StackOverflow Users Are Brilliant 
相关问题