Linux 从特定字段中删除csv中包含少于x个字符串/字数的行

Linux 从特定字段中删除csv中包含少于x个字符串/字数的行,linux,bash,sed,Linux,Bash,Sed,如果我有一个类似于以下内容的csv: 1999, random strings go here, £50.00, 983903893 1957, Another lacklustre line, £99.00, 3983093 1987, Adventure UK, £83.83, 39939 1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983 如何删除字段2包含3个或更少单词的行。因此,输出将是: 1999

如果我有一个类似于以下内容的csv:

1999, random strings go here, £50.00, 983903893
1957, Another lacklustre line, £99.00, 3983093
1987, Adventure UK, £83.83, 39939
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
如何删除字段2包含3个或更少单词的行。因此,输出将是:

1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
我很想说我想使用sed,因为它可以在不需要创建新文件的情况下更改文件

我知道如何引用第二个字段,并使用sed从csv中删除单个单词或符号。例如,我可以使用此选项删除问号:

sed -ri ':b s/^([^,]*,[^,]*)\?/\1 /g; t b'
但是如果有三个或更少的单词,我怎么告诉他我想删除整行呢?这是我正在努力解决的问题。谢谢

编辑:这是一个实际的文件片段,请参考这个而不是我的原始示例-它的格式相同,但数据不同,这似乎影响了Jean-François Fabre answer中建议的sed行处理数据的方式:

142106729748,Rocky Horror Book,http://www.ebay.co.uk/itm/Rocky-Horror-Book-/142106729748,0.99
162189532196,Total Film Issue 10,http://www.ebay.co.uk/itm/Total-Film-Issue-10-/162189532196,0.75
162189528365,Total Film Issue 9,http://www.ebay.co.uk/itm/Total-Film-Issue-9-/162189528365,0.99
172328113931,Captain America 163 Silver Age,http://www.ebay.co.uk/itm/Captain-America-163-Silver-Age-/172328113931,2.5
232069020935,Football Picture Story Monthly,http://www.ebay.co.uk/itm/Football-Picture-Story-Monthly-/232069020935,0.25
262606117082,The geographical Tradition ,http://www.ebay.co.uk/itm/geographical-Tradition-/262606117082,10.0
401182170339,Naruto Official Fanbook,http://www.ebay.co.uk/itm/Naruto-Official-Fanbook-/401182170339,3.0

塞德勉强做到了,但做到了

sed -r '/^[^,]+, (\w+[, ]){4,}/!d' text.txt
小说明:

跳过第一个字段 {4,}匹配下一个字段中由空格或逗号分隔的4个或多个单词 这个d命令不会删除那些不匹配的 需要-r选项或某些内容无法正常工作\w 结果:

1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
事实上,我不得不用手固定英镑符号:

编辑:最好以防标签在文件中找到它的方式。谢谢波通

 sed -r '/^[^,]*,([[:space:]]+[^[:space:],]+){4}/!d'

塞德勉强做到了,但做到了

sed -r '/^[^,]+, (\w+[, ]){4,}/!d' text.txt
小说明:

跳过第一个字段 {4,}匹配下一个字段中由空格或逗号分隔的4个或多个单词 这个d命令不会删除那些不匹配的 需要-r选项或某些内容无法正常工作\w 结果:

1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
事实上,我不得不用手固定英镑符号:

编辑:最好以防标签在文件中找到它的方式。谢谢波通

 sed -r '/^[^,]*,([[:space:]]+[^[:space:],]+){4}/!d'
使用awk:

split$2,arr,通过在空格上拆分第二个字段来创建数组arr

iflengtharr>=4仅当数组长度>=4时,打印才会打印记录

例如:

使用awk:

split$2,arr,通过在空格上拆分第二个字段来创建数组arr

iflengtharr>=4仅当数组长度>=4时,打印才会打印记录

例如:

Perl解决方案:

perl -waF, -i~ -ne 'print if 3 < split " ", $F[1]' -- text.txt
-w打开警告 -n逐行读取输入 -a将每个输入行拆分为@F数组 -F告诉Perl如何拆分它,在本例中它使用逗号 -我就地修改文件,~将用作备份的后缀 在标量上下文中返回字段数。

Perl解决方案:

perl -waF, -i~ -ne 'print if 3 < split " ", $F[1]' -- text.txt
-w打开警告 -n逐行读取输入 -a将每个输入行拆分为@F数组 -F告诉Perl如何拆分它,在本例中它使用逗号 -我就地修改文件,~将用作备份的后缀
在标量上下文中,返回字段的数量。

sed用于对单个行进行简单替换,仅此而已。对于任何其他内容,您都应该使用awk:

$ awk -F' *, *' 'split($2,t,/ */)>3' file
1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

sed是对单个行的简单替换,仅此而已。对于任何其他内容,您都应该使用awk:

$ awk -F' *, *' 'split($2,t,/ */)>3' file
1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

如果问题涉及多个字段、更多的拆分等,那么将是sed解决方案的更好替代方案。。因此,如果问题涉及多个字段、更多拆分等,那么+1将是sed解决方案的更好替代方案。。所以+1我可能说得太快了,因为某种原因,当我在我的实际csv上尝试它时,它返回了600+行中的3行,其中大多数都有4个以上的单词!?@Jean-François Fabre查看我添加到问题中的数据,出于某种原因,您的代码行无法使用它。执行该行时,没有任何内容通过。我不明白为什么它会与我的原始样本数据不同,因为csv格式是相同的。也许需要放松和收紧regexp?一点sed-r'/^[^,]*,[[:space:]+[^[:space:],]+{4}/!d'文件,即第一个字段可能不存在或空格可能不是空格。或者,有可能逃脱?如果是这样的话,你需要用其他东西替换它们,然后进行测试。当然,不要忘了在测试之后恢复它们!。你说得对。我会更激进:其他解决方案,如perl或awk更灵活。我可能说得太早了,因为某些原因,当我在实际的csv上尝试它时,它会返回600+中的3行,并且大多数都有4个以上的单词!?@Jean-François Fabre查看我添加到问题中的数据,出于某种原因,您的代码行无法使用它。执行该行时,没有任何内容通过。我不明白为什么它会与我的原始样本数据不同,因为csv格式是相同的。也许需要放松和收紧regexp?一点sed-r'/^[^,]*,[[:space:]+[^[:space:],]+{4}/!d'文件,即第一个字段可能不存在或空格可能不是空格。或者,有可能逃脱?如果是这样的话,你需要用其他东西替换它们,然后进行测试。当然,不要忘了在测试之后恢复它们!。你说得对。我将更激进一些:其他解决方案,如perl或awk更灵活
如果您还发布了相关的预期输出,则非常有用。此外,在描述需求时,始终将重点放在积极的方面——在本例中,根据您希望从输入中选择的内容来表达需求,而不是您希望删除的内容。使需求更清晰,并可导致更简单的解决方案。如果同时发布相关的预期输出,则发布新输入更有用。此外,在描述需求时,始终将重点放在积极的方面——在本例中,根据您希望从输入中选择的内容来表达需求,而不是您希望删除的内容。使需求更清晰,并可以导致更简单的解决方案。这是成功的,正是我所需要的。干杯。我可以问一下,如果字段分隔符是文件中的一个管道而不是一个逗号,我是将行中的两个逗号都替换掉,还是将其中一个替换为管道?@nmh:如项目符号列表中所述,您需要-F'\\|'使用竖线作为分隔符反斜杠,以防止在正则表达式中有特殊含义,需要引号,因为管道是shell的专用工具。第二个逗号分隔要拆分的参数。cool perl-waF'\\\''-i~-ne'print if 3