2017-01-11 51 views
1

在我的Linux目录中,我有6个文件。 5个文件是txt文件,1个文件是.tar.gz类型的文件。我怎样才能打印到终端只有txt文件的名称?如何在linux终端上只打印txt文件?

directory :dir 
content: 
ex1, ex2, ex3, ex4, ex5, ex6.tar.gz 
+2

使用[通配符](http://www.linfo.org/wildcard.html) – myaut

+0

'ls * .txt'应该可以做到。 –

+2

@ILikeTau你在哪里可以看到他的内容中有'.txt'扩展名? – Barmar

回答

0

由于您没有文件扩展名(.txt),我会尝试使用排除来完成。

ls | grep -v tar.gz

如果您有多个类型,请使用扩展名。

0

命令'file'后跟一个文件名,将返回文件的类型。

您可以遍历目录中的文件,将每个文件名用作“文件”命令的输入,如果是文本文件,则输出该文件名。

以下包括从文件命令一些额外的输出,我不知道怎么又删除,但它确实给你你想要的文件名:

​​

你可以把它变成壳脚本放在您想从中获取文件名的目录中,然后从命令行运行它。

+0

空白的路径?另请参见[Unix和Linux协议栈](http://unix.stackexchange.com/)上的[在名称中使用空格来循环文件?](http://unix.stackexchange.com/q/9496/56041) 。 – jww

+0

'file $ f 2>/dev/null | grep文本' –

+0

最有可能抑制额外的东西 –

0

更新回答

如@ hek2mgl评价所指出的,一个更强大的解决方案是分离使用NULL字符(可能不是在文件名中发生)的文件名,并且将处理包含换行符的文件名,并冒号:

file -0 * | awk -F'\0' '$2 ~ /text/{print $1}' 

原来的答案

我这样做:

file * | awk -F: '$2~/text/{print $1}' 

运行file看每个文件的类型,并传递由冒号分隔的名称和类型,以awkawk然后在第二个字段中查找单词text,如果它找到它,则打印第一个字段 - 这是文件名。

尝试运行它自己以下简单的命令来看看它是如何工作的:

file * 
+1

如果文件名中有冒号,会发生什么情况? –

+0

@MadPhysicist好点。这同样适用于空格。 'file'有一个选项'-print0',可以使用:'file -0 * | awk -F'\ 0''$ 2〜/ text/{print $ 1}'' – hek2mgl

+0

'文件-0'在POSIX版本的文件上不可用。 – dawg

0

使用file命令的意见是正确的。这里的问题是解析这个命令的输出,因为(1)文件名可以包含任何字符,(2)file命令的具体输出有点不可预知,因为它取决于所谓的魔术文件是存在的。

如果我们依靠的事实file命令的输出的说明文字 - 即那部分解释了什么文件,它是 - 总是包含单词文本如果是文本的文件,它永远不会包含冒号,我们可以如下处理它:

输出中的最后一个冒号必须将解释的文件名与文件名分开。左边的所有内容都是文件名,如果在右边部分出现text(注意文本!之前的前导空格)这个词,我们就有一个文本文件。

这仍然给我们留下了那些(希望罕见)情况下,文件名包含非打印字符,它们将被转换为自己的八进制等价的,这可能会或可能不是你想看到的是。您可以通过将-r选项传递给文件命令来取消该选项。如果你想进一步处理这个文件名,而不是只显示给用户,这很有用,但它可能会破坏你的解析逻辑,特别是如果文件名包含一个换行符。

最后,不要忘记,无论如何,你会看到什么系统认为一个文本文件。这不一定是定义为一个文本文件。

0

指定文件的这个目录:

$ file * 
1.txt:  UTF-8 Unicode (with BOM) text, with CRLF line terminators 
2.pdf:  PDF document, version 1.5 
3.pdf:  PDF document, version 1.5 
4.dat:  data 
5.txt:  ASCII text 
6.jpg:  JPEG image data, JFIF standard 1.02, aspect ratio, density 100x100, segment length 16, baseline, precision 8, 2833x972, frames 3 
7.html:  HTML document text, UTF-8 Unicode text, with very long lines, with no line terminators 
8.js:  UTF-8 Unicode text 
9.xml:  XML 1.0 document text 
A.pl:  a /opt/local/bin/perl script text executable, ASCII text 
B.Makefile: makefile script text, ASCII text 
C.c:  c program text, ASCII text 
D.docx:  Microsoft Word 2007+ 

你可以看到,是纯ASCII的文件只有5.txt,9.xml,和A-C。其余的是根据file的二进制或UTF。

您可以使用Bash glob遍历文件并使用file来测试每个文件。这节省不必解析的file为文件名的输出,但依赖于file精确识别您认为什么是“文”:

for fn in *; do 
    [ -f "$fn" ] || continue 
    fo=$(file "$fn") 
    [[ $fo =~ ^"$fn":.*text ]] || continue 
    echo "$fn" 
done  

如果您不能使用file,这当然是最简单的方法,你可以打开文件并查找二进制字符。使用Perl为:

for fn in *; do 
    [ -f "$fn" ] || continue 
    head -c 2000 "$fn" | perl -lne '$tot+=length; $cnt+=s/[^[:ascii:]]//g; END{exit 1 if($cnt/$tot>0.03);}' 
    [ $? -eq 0 ] || continue 
    echo "$fn" 
done  

在这种情况下,我找了ASCII与非ASCII的前2000个字节的文件的百分比。 YMMV,但允许查找file将报告为UTF的文件(因为它具有二进制BOM),但大多数文件是ascii。

对于该目录中,这两个Bash脚本报告(与我的每个文件的注释):

1.txt  # UTF file with a binary BOM but no UTF characters -- all ascii 
4.dat  # text based configuration file for a router. file does not report this 
5.txt  # Pure ascii file 
7.html # html file 
8.js  # Javascript sourcecode 
9.xml  # xml file all text 
A.pl  # Perl file 
B.Makefile # Unix make file 
C.c  # C source file 

由于file不考虑所有的ASCII文件4.dat是文本,它不被首次报道Bash脚本,但在第二个。否则 - 相同的输出。