我需要验证和匹配目录(/home/user/example)中有文件。每个文件都有一个控制文件和数据文件。我想检查每个文件是否都有另一个文件的对应文件。例如,如果 example.ctl 与 example.out 匹配,或者 example.out 与 example.ctl 具有对应的文件。
我编写了一个嵌套的 for 循环和许多 if else 语句。但这对于这样的基本检查来说似乎太复杂了。我想看看是否有人有更好的解决方案。
目录中的示例文件:
example.ctl
example.out
example_1.ctl
example_1.out
example_2.ctl
example_2.out
答案1
comm <(basename -a -s.ctl *.ctl | sort) <(basename -a -s.out *.out | sort)
请参阅comm(1)
,特别是标志-12
将仅列出具有两个后缀的文件。
答案2
第一个变体
它遍历所有文件名并检查每个文件,是否有一对并打印相应的消息。
for i in *; do
base=${i%.*}
if [ -e "${base}.out" -a -e "${base}.ctl" ]; then
printf 'file "%s" has a pair\n' "$i"
else
printf 'file "%s" has not a pair\n' "$i"
fi
done
第二种变体
它仅遍历.ctl
文件并检查当前.ctl
文件是否有一对 -.out
文件。因此,它仅打印配对的文件,忽略其余的 - 未配对的文件。
for i in *.ctl; do
base=${i%.*}
if [ -e "${base}.out" ]; then
printf 'file "%s" has a pair "%s"\n' "$i" "${base}.out"
fi
done
答案3
您正在尝试检测丢失的 .ctl和.out 文件,因此您需要检查两种方式。执行此操作的一个简单方法(如果您的文件名不包含特殊字符,包括空格,并且仅包含一个点)是
- 查找所有带有
find . -type f
,的文件 - 使用 删除每个扩展名
cut --delimiter=. --fields=1
, sort --unique
删除重复项,- 循环遍历它们
while read name
,最后 - 检查每个文件是否存在
[[ -e "${name}.ctl" ]] || echo "${name}.ctl" >&2
并且 .out 是否相同。
答案4
您可以循环文件并派生输出和控制文件的预期文件名。完成后,您可以检查两者是否存在:
for item in *.out *.ctl
do
base="${item%???}"
out="$base.out" ctl="$base.ctl"
[ -f "$out" -a ! -f "$ctl" ] && echo "$out is missing $ctl" >&2
[ -f "$ctl" -a ! -f "$out" ] && echo "$ctl is missing $out" >&2
done