从文件中删除新行、空格

从文件中删除新行、空格

我的目录中有很多文件,每个文件如下所示:

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 系统上,您可以使用 GNUawksed支持多字节字符的 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 语言环境中的输出)。

通过uconvICU 项目,您可以:

<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}'

要就地修改文件,您可以使用gawkinplace模块:

gawk -i /usr/share/awk/inplace.awk gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}' file

不使用-i inplaceas尝试首先从当前工作目录gawk加载inplace扩展(asinplace或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk的路径可能会有所不同,请参阅输出inplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

答案2

你不需要-name '*'像你想要的那样处理每一个文件(*无论如何都会匹配每个文件,因此没有任何区别)。但是,您可能只想-type f处理常规文件(而不是目录等)

要删除非字母的任何内容,您可以使用

tr -cd '[:alpha:]' <file

补足-c给定的字符集,并且[:alpha:]仅匹配字母字符。指示删除匹配-dtr字符。

因此,您可能想要执行的命令是

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

https://docs.raku.org/language/unicode
https://raku.org

相关内容