我有一个文件,它是文件名和相应转录本之间的映射。文件名和记录用制表符分隔。
文件的转录可能包含一个或多个由单个空格分隔的单词。以下是文件的布局,
[filename] [tab space] [trancription]
在某些行中,转录栏是空的。这些行的形式为
[filename]
即该文件名没有可用的转录本。
现在,我的工作是确保只选择那些具有文件名和转录的行(即转录列不为空的文件)。
我尝试了以下命令
(1) awk 'NF>2' filename
(2) awk 'NF==2' filename
(3) awk 'NF>1' filename
但没有得到结果
另外,当我使用命令时
(4) awk ' NF==2 {print $0} ' myfile > newfile
我还得到了那些只有一列的行,即“文件名”字段。
当我写入时NF<1
没有输出(如预期)当我NF<2
再次写入时没有输出(奇怪,它应该显示只有一列的行)当我写入时NF ==3
我得到那些恰好有两列的行(再次令人困惑)
有什么问题吗?这真的很令人困惑。
现在我向您发送输入样本
M07UP36A0821I40.wav
M07UP36A0821I41.wav
M07UP36A0821I410.wav gaajara <bn>
M07UP36A0821I411.wav tiina sau <pau> taintaaliisa
M07UP36A0821I412.wav geehuun anya <bn>
M07UP36A0821I413.wav geehuun daraa <babble>
现在我使用命令
grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' cll
该命令没有给出任何输出(无论是在终端上还是在重定向的文件中)。
现在有一件有趣的事情需要注意:
当输入文件包含
M07UP36A0822I413.wav <bn> geehuun daraa <horn> <babble>
M07UP36A0822I414.wav
M07UP36A0822I415.wav gudxqa piilaa <horn> <babble>
M07UP36A0822I416.wav <vn> gudxqa
M07UP36A0822I417.wav gudxqa
M07UP36A0822I418.wav gudxqa anya <babble>
M07UP36A0822I419.wav harii matxara <bn> <babble>
再次,使用相同的命令
grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' foo
终端已开始显示输出。此处的输出为
M07UP36A0822I417.wav gudxqa
我想要的文件 foo 的输出是那些完整的行(第一列和第二列都必须在那里)这是所需的输出
M07UP36A0822I413.wav <bn> geehuun daraa <horn> <babble>
M07UP36A0822I415.wav gudxqa piilaa <horn> <babble>
M07UP36A0822I416.wav <vn> gudxqa
M07UP36A0822I417.wav gudxqa
M07UP36A0822I418.wav gudxqa anya <babble>
M07UP36A0822I419.wav harii matxara <bn> <babble>
我在文件 cll 上使用了以下命令(我的问题中的第一个示例)
awk -F'\t' '(NF !=2) { print "line: " NR " does not have 2 columns: " $0 ;}' cll
结果显示在终端上。结果是
line: 1 does not have 2 columns: M07UP36A0821I40.wav
line: 2 does not have 2 columns: M07UP36A0821I41.wav
line: 3 does not have 2 columns: M07UP36A0821I410.wav gaajara <bn>
line: 4 does not have 2 columns: M07UP36A0821I411.wav tiina sau <pau> taintaaliisa
line: 5 does not have 2 columns: M07UP36A0821I412.wav geehuun anya <bn>
line: 6 does not have 2 columns: M07UP36A0821I413.wav geehuun daraa <babble>
答案1
使用grep
:
grep -E '^[^\s]+\s+[^\s]+$' file.txt
[^\s]+
将包含第一列,然后是任意数量的空格\s+
,最后是第二列(最后一列)^
表示行的开始并$
表示行的结束
POSIX-ly:
grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' file.txt
答案2
其他答案,使用\s+
过度匹配!\s
也匹配数据中出现的空格。您正在寻找的是“Field_not_containing_TAB”,然后是“Tab”,然后是“Field_not_containing_TAB”。或者,用正则表达式来说,
egrep '^[^
Tab]+
Tab[^
Tab]+$' file.txt
Space注意:我的 rexexp 中的 ' 之间不应有任何字符egrep
。由于我使用了kbd
格式化标签,您可以在那里看到它们,我必须使用该标签才能使其Tab可见。
正则表达式匹配(或使用选项-v
,egrep
不匹配)提供的数据。
答案3
对你来说,两列是:something[TAB]something,something 中可以有一个空格。所以只需告诉 awk 你的字段分隔符是一个选项卡:
awk -F'\t' '(NF==2)'
找出其他人:
awk -F'\t' '(NF !=2) { print "line: " NR " does not have 2 columns: " $0 ;}'
编辑:您似乎“误导”了文件的结构:您说它将包含 1 个单词,或 1 个单词,一个制表符,以及 1 个或多个单词(用空格分隔)。如果是这样,上面的方法应该有效。但是,考虑到文件上上述命令的结果,我猜它是:1 个单词,[空格或制表符],也许还有单词[以及其间的空格或制表符]
因此解决方案变为:
awk -F'[\t ]+' '(NF>=2)' #words are separated by space&tabs, and we want at least 2 words [a filename, and its description]
变体:输出第二个单词非空的任何行:
awk -F'[\t ]+' '(length($2)>0)' #words are separated by space&tabs, and we want athe 2nd word to be non empty
#or, one that also verifies the 1st word is non empty:
awk -F'[\t ]+' '(length($1)>0 && length($2)>0)' #1st and 2nd words are non-empty