我的目录中有很多文件,每个文件如下所示:
AAA
AA
AAAAAA
A
AAAA
我想以此结束:
AAAAAAAAAAAAAAAA
这样当我跑步时:
find ./ -name '*' -exec wc -m {} +
我返回 16,而不是 20+,具体取决于计算了多少新行/空格。
基本上,我想从文件中删除所有内容,除非它是一封信。
答案1
请注意,如果从文件中删除每个换行符,即使是最后一个,那么它就不再是文本文件(除非文件最终为空),因为文本文件包含一系列文本行,文本行由换行符分隔人物。
现在,要删除除字母字符(任何字母表)之外的所有字符,正如 @Kusalanada 所说,POSIXly,您可以使用tr -cd '[:alpha:]'
.
现在,不幸的是,通过一些tr
实现,包括 GNUtr
,这不适用于多字节字符。在 UTF-8 语言环境中,这意味着除 ASCII 字符之外的所有字符。
在 GNU 系统上,您可以使用 GNUawk
或sed
支持多字节字符的 GNU:
<file sed 's/[^[:alpha:]]//g' | tr -d '\n'
<file awk -v ORS= '{gsub(/[^[:alpha:]]/, ""); print}'
该语法不是 GNU 特定的,但您会发现一些不支持多字节字符的非 GNU sed
/实现。awk
请注意,GNU sed
/awk
至少不会删除不形成有效字符的字节序列(例如printf 'à b \200\n'
UTF-8 语言环境中的输出)。
通过uconv
ICU 项目,您可以:
<file uconv -i -x '[^[:Letter:]]>;'
其中-i
告诉uconv
跳过无法解码的输入。
但这仅适用于 UTF-8 数据。请注意,它使用 Unicode 字符属性(Unicode 的某些版本),而不是由您的语言环境决定什么是字母或不是字母。
使用 GNU grep
,您可以使用:
<file grep -o '[:alpha:]' | tr -d '\n'
或者如果使用 PCRE 支持构建(使用 Unicode 属性):
<file grep -Po '\pL' | tr -d '\n'
对于 GNU awk
,跳过无效输入的另一种方法是使用RS
:
<file gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}'
要就地修改文件,您可以使用gawk
的inplace
模块:
gawk -i /usr/share/awk/inplace.awk gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}' file
不使用-i inplace
as尝试首先从当前工作目录gawk
加载inplace
扩展(asinplace
或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk
的路径可能会有所不同,请参阅输出inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
答案2
你不需要-name '*'
像你想要的那样处理每一个文件(*
无论如何都会匹配每个文件,因此没有任何区别)。但是,您可能只想-type f
处理常规文件(而不是目录等)
要删除非字母的任何内容,您可以使用
tr -cd '[:alpha:]' <file
补足-c
给定的字符集,并且[:alpha:]
仅匹配字母字符。指示删除匹配-d
的tr
字符。
因此,您可能想要执行的命令是
tr -cd '[:alpha:]' <file | wc -m
对于每个文件。
由于这太复杂而无法find
直接执行,因此您必须使用内联脚本:
find . -type f -exec sh -c '
for pathname do
tr -cd "[:alpha:]" <"$pathname" | wc -m
done' sh {} +
在这里,内联sh -c
脚本将从 中获取批量文件路径名作为参数find
。将为每个文件执行管道。
答案3
使用乐(以前称为 Perl_6)
~$ raku -e 'S:g/ <-alpha> //.put given lines;' file
#OR
~$ raku -e 'S:g/ <- :L > //.put given lines;' file
或者:
~$ raku -e 'S:g/ <-alpha> //.put given slurp;' file
#OR
~$ raku -e 'S:g/ <- :L > //.put given slurp;' file
Raku 内置对 Unicode 的高级支持,因此无需加载外部库即可计算多字节字符。正则表达式字符类:L
表示 Unicode 字母,并且<- :L >
意味着“除了”Unicode 字母之外的所有内容都将在替换中被删除。
输入示例(第一行有 ~ 6 个尾随空格,第六行有 ~ 12 个空格):
AAA
AA1234
ÀÁÂÃÄÅÆ
1234
AAAA
示例输出:
AAAAAÀÁÂÃÄÅÆAAAA
计算字符数:
~$ raku -e 'S:g/ <- :L > //.raku.put given lines;' file
"AAAAAÀÁÂÃÄÅÆAAAA"
~$ raku -e 'S:g/ <- :L > //.chars.put given lines;' file
16
~$ raku -e 'S:g/ <- :L > //.comb.elems.put given lines;' file
16