编辑

编辑

我正在尝试在目录中搜索不以句点结尾的文件。我试图列出最后一个 ascii 字符的文件名,该字符后面不跟句点/标点符号。我已经查看了所有内容,但到目前为止没有任何效果。任何帮助将不胜感激!

for file in ./dir/*;
do grep -o '[^[:punct:]]$' $file

输出:

filename  f
filename  d
filename  e

文件名后面的字母代表文件中的最后一个字符,后面不跟标点符号。

空文件应与不以标点符号结尾的文件区别对待。空文件将被忽略。我特别指的是文件内的句点/标点符号,忽略文件名。

我被迫使用 mawk 版本 1.3.4

答案1

这可能是您想要做的,使用 GNU awk ENDFILE

awk 'ENDFILE {
    if ( FNR ) {
        c = substr($0,length(),1)
        if ( c !~ /[[:punct:]]/ ) {
            print FILENAME, c
        }
    }
}' dir/*

或使用任何 POSIX awk:

awk '
    FNR == 1 { prt(); fname=FILENAME }
    { lastRec = $0 }
    END { prt() }
    function prt(    c) {
        c = substr(lastRec,length(),1)
        if ( c !~ /[[:punct:]]/ ) {
            print fname, c
        }
    }
' dir/*

或者如果您的 awk 不是 POSIX(如您当前拥有的 mawk 1 ),那么要使其与任何 awk 一起使用,请替换[[:punct:]]为包含硬编码标点字符列表(非字母、数字的字符)的方括号表达式、控制字符或空格字符),例如[-.,!=+]等,或将比较从!~更改为~并更改[[:punct:]]为非标点字符的字符列表(非字母、数字、控制字符或空格字符的字符),例如[a-zA-Z0-9 \t]等。

答案2

这可以使用 GNU sed 以及将文件列表视为单独文件的选项和F打印文件名的命令来完成。

$ sed -sn '${s/.*\(.\)$/\1/;/[^[:punct:]]/{F;l}}' ./*

./fileone
a$

./filetwo
s$

假设这些文件都是文本文件。如果不是,可能会打印多个字符。该l命令用于避免控制台上原始二进制文件输出的问题。

描述

第一行$仅匹配最后一行。在该行上执行外部{...}.

s/.*\(.\)$/\1/替换最后一个字符的整行。在具有一个或多个字符的行上。空行不会改变。

然后,在没有punct( /[^[:punct:]]/) 的行上执行第二对大括号内的内容{...}。当然,这要求至少匹配一个字符,这将拒绝空行。

在最后一行没有的地方执行的代码punctF打印文件名并l打印该行最后一个字符的值(如果没有ascii则进行编码)。

编辑

避免二进制文件的更严格的版本可能是:

sed -sn '${/[[:print:]\t]$/!d;s/.*\(.\)$/\1/;/[^[:punct:]]/{F;l}}' ./*

这不会处理最后一个字符不存在的文件print(所有数字、字母(大写和小写)、标点符号和空格)或制表符。

答案3

如果您需要查找不带标点符号结尾的文件内容:

for f in ./* ; do tail -n 1 "$f" | grep -qv '[^[:punct:]]$' || echo "$f" ; done

如果您需要查找不带标点符号结尾的文件名:

find . | grep -v '[[:punct:]]$'

相关内容