![shell 脚本或 awk 脚本删除第一列/字段为空的文件](https://linux22.com/image/122954/shell%20%E8%84%9A%E6%9C%AC%E6%88%96%20awk%20%E8%84%9A%E6%9C%AC%E5%88%A0%E9%99%A4%E7%AC%AC%E4%B8%80%E5%88%97%2F%E5%AD%97%E6%AE%B5%E4%B8%BA%E7%A9%BA%E7%9A%84%E6%96%87%E4%BB%B6.png)
我的目录中有一堆 CSV 文件。我想重命名第一列不包含数字或为空的文件。新文件名应为 filename.bad
我尝试了这个 awk 命令,但它不起作用。
awk '{ if (! ($1 ~ /[0-9]/)) print $1 }' *.csv .
这些文件看起来像这样。文件1.csv:
123,ggg,fhghgh,fhgh
345,bla,bla,bla
文件2.csv:
234,bla,bla,bla
,bla,bla,bla
这是一个坏文件,因为它缺少编号,因此应该重命名并删除它。
答案1
去除第一列不包含数字或为空的文件:
简单的grep
方法:
for f in *.csv; do grep -Eq '^(,|[^0-9])' "$f" && rm "$f"; done
答案2
$1
包含第一个字段的内容,但我认为您想打印文件名。另外,默认情况下awk
假定字段由空格分隔,但您的字段由逗号分隔。
我们可以告诉awk
使用逗号作为分隔符-F,
,在 GNU awk 中,有一个FILENAME
包含当前文件名的变量。
然后添加针对第一个字段的测试,例如$1 !~ /[0-9]/
选择第一个字段不包含数字的所有行,或者$1 !~ /^[0-9]+$/
选择第一个字段为空或不完全由数字组成的行。 (我不确定您想要的确切测试是什么。如果您需要允许小数点或前导减号,则需要进行调整。)
所以,仍然假设 GNU awk,类似这样的东西应该打印你想要的文件名:
awk -F, '$1 !~ /^[0-9]+$/ { print FILENAME; nextfile}' *.csv
(请注意,完全空的行也会触发此操作,并且如果您的文件名包含换行符,则该操作不起作用。)
然后将其包装在循环中以重命名或删除文件。
答案3
怎么样:
for f in *csv; do
awk -F, '$1!~/^[0-9][0-9]*$/{exit 1}' "$f" || echo rm -- "$f"
done
awk
如果输入文件中的任何行的第一个(逗号分隔)字段不完全由一个或多个数字组成,则脚本将以非=0 退出状态退出。这||
意味着“如果左侧失败,则执行右侧操作”,因此如果以非 0 退出状态退出,它将执行rm
该文件。awk
删除echo
使其真正删除文件。
或者,你可以这样做:
for f in *csv; do grep -q '^,' "$f" && echo rm -- "$f"; done
因此,如果任何行以 开头,
,请删除该文件。但这会错过第一个字段不是数字的任何行。如果您也想要这些,您可以使用:
for f in *csv; do grep -qE '^(,|[^0-9]+),' "$f" && echo rm -- "$f"; done
答案4
以下命令重命名第一列为空或第一列不包含数字的文件
命令:
awk -F "," '$1=="" || $1 ~ !”[0-9]” {print "mv" " " FILENAME " " FILENAME".bad"}' * | sh
如果您要删除第一列为空或第一列不包含数字的文件。
awk -F "," '$1=="" || $1 ~ !”[0-9]” {print “rm -rvf” “ “ FILENAME}’ * | sh