我正在尝试在目录中搜索不以句点结尾的文件。我试图列出最后一个 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:]]/
) 的行上执行第二对大括号内的内容{...}
。当然,这要求至少匹配一个字符,这将拒绝空行。
在最后一行没有的地方执行的代码punct
是F
打印文件名并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:]]$'