![](/img/trans.png)
[英]How to create zip archive with files with only .txt extension in Linux using terminal
[英]How to print only txt files on linux terminal?
在我的Linux目录中,我有6个文件。 5个文件是txt文件,1个文件是.tar.gz类型文件。 如何只在终端上打印txt文件的名称?
directory :dir
content:
ex1, ex2, ex3, ex4, ex5, ex6.tar.gz
命令'file',后跟文件名,将返回文件的类型。
您可以遍历目录中的文件,使用每个文件名作为'file'命令的输入,如果是文本文件,则打印该文件名。
以下包括来自file命令的一些额外输出,我不知道如何删除,但它确实为您提供了所需的文件名:
#!/bin/bash
for f in *
do
file $f | grep text
done
您可以将其放入要从中获取文件名的目录中的shell脚本,然后从命令行运行它。
因为你没有文件扩展名(.txt),我会尝试排除。
ls | grep -v tar.gz
如果您有多种类型,请使用扩展名。
更新的答案
正如@ hek2mgl在评论中指出的,一个更强大的解决方案是使用nul字符(可能不会出现在文件名中)来分隔文件名,这将处理包含换行符和冒号的文件名:
file -0 * | awk -F'\0' '$2 ~ /text/{print $1}'
原始答案
我会这样做:
file * | awk -F: '$2~/text/{print $1}'
运行file
以查看每个文件的类型,并将名称和类型传递awk
冒号分隔的awk
。 awk
然后在第二个字段中查找单词text
,如果找到它,则打印第一个字段 - 即文件名。
尝试单独运行以下更简单的命令,看看它是如何工作的:
file *
使用file
命令的建议是正确的。 这里的问题是解析这个命令的输出,因为(1)文件名可以包含任何字符,(2) file
命令的具体输出有点不可预测,因为它取决于所谓的魔术文件是如何当下。
如果我们依赖于file
命令输出的说明文本 - 即解释它是什么文件的部分 - 如果它是文本文件总是包含单词text ,并且它从不包含冒号,我们可以处理如下:
输出中的最后一个冒号必须将文件名与说明分开。 一切左侧是文件名,如果字text
(注意文本之前前导空格!)在右边出现,我们有一个文本文件。
这仍然让我们看到那些(希望很少见)文件名包含不可打印字符的情况,它们将被翻译成它们的八进制等价物,这可能是也可能不是你想要看到的。 您可以通过将-r
选项传递给file命令来抑制此操作 。 如果您希望进一步处理此文件名而不是仅将其显示给用户,这很有用,但它可能会破坏您的解析逻辑,尤其是在文件名包含换行符的情况下。
最后,不要忘记在任何情况下,您都会看到系统认为文本文件的内容。 这不一定与您定义为文本文件的内容相同。
鉴于此文件目录:
$ 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和AC。 其余的是根据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
在这种情况下,我在文件的前2000个字节中寻找ascii与非ascii的百分比。 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脚本不报告它,而是由第二个报告。 否则 - 相同的输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.