我不经常这样做,而且当我这样做时总是对时间很敏感。我有下面的 sed 脚本,它从超过一百万个文件中提取数字模式。我需要将其发送到 AWK,因此当找到匹配的模式时,它会打印找到它的文件名。行数会很大,但不要贪婪。
期望的输出
文件名1 000-323423-33
文件名2 000-323423-33
文件名3 000-323423-33
我尝试了各种方法,但没有任何效果,有经验的人可以提供正确的指导吗?先感谢您!
#!/bin/sh
#shopt -s nullglob
FILES=/mnt/c/temp/1/*.txt
for f in $FILES
do
echo "Processing $f"
sed -nr \
-e '/[0-9]{3}-[0-9]{6}-[0-9]{2}/{
s/.*([0-9]{3}\-[0-9]{6}\-[0-9]{2}).*/\1/
G
p
}' $f
done
答案1
看来你的任务就是grep
正在做的事情。如果您确实不需要冒号,请使用 替换它们为空格tr
,假设文件名中不存在冒号。
grep -Eon '[0-9]{3}-[0-9]{6}-[0-9]{2}' *.txt | tr ':' ' '
输出将类似于:
file1 10 000-323423-33
file2 20 000-323423-34
file3 30 000-323423-35
file3 31 000-323423-36
答案2
@thanasisp 是对的,grep
是这项工作的理想选择。
使用awk,你可以写
awk -v OFS=, '
match($0, /[0-9]{3}-[0-9]{6}-[0-9]{2}/) {
print FILENAME, FNR, substr($0, RSTART, RLENGTH)
}
' /mnt/c/temp/1/*.txt
参考:https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html
对于这么多文件,您可能会收到“参数列表太长”错误。这时候你就需要find
find /mnt/c/temp/1/ -type f -name '*.txt' -exec awk -v OFS=, '
match($0, /[0-9]{3}-[0-9]{6}-[0-9]{2}/) {
print FILENAME, FNR, substr($0, RSTART, RLENGTH)
}
' '{}' +