我在一个hadoop目录下有几十万个文件,我需要调试它们。我正在寻找删除超过 3 个月的文件,并且我正在尝试分批删除我在该目录中以这种情况获得的一千个文件,但我遇到了问题。在众多文件中,有些文件的名称中包含一些空格,例如“hello word.csv”。我已经尝试过批处理,在 unix 中使用数组或将输出写入文件,但不管怎样,它在执行 hdfs dfs -rm -f
时无法识别其中的文件有了这个,我找到了文件
list_files=$(hdfs dfs -ls "${folder_in}" | awk '!/^d/ {print $0}' | awk -v days=${dias} '!/^d/ && $6 < strftime("%Y-%m-%d", systime() - days * 24 * 60 * 60) { print substr($0, index($0,$8)) }')
我想通过在shellscript中加载一个数组来批量删除HDFS文件,如下所示:
while IFS="" read -r file; do
files+=(\"${file}\")
echo -e "\"$file\"" > ${PATH_TMP}/file_del_proof.tmp
done <<< "$list_files"
我尝试使用以下脚本删除 HDFS 文件:
total_lines=$(wc -l < "${PATH_TMP}/file_del_proof.tmp")
start_line=1
while [ $start_line -le $total_lines ]; do
end_line=$((start_line + batch_size - 1))
end_line=$((end_line > total_lines ? total_lines : end_line))
hdfs dfs -rm -f -skipTrash $(awk -v end_line=${end_line} -v start_line=${start_line} 'NR >= start_line && NR <= end_line' "${PATH_TMP}/file_del_proof.tmp")
start_line=$((end_line + 1))
done
问题是在那个列表中出现了一些名称中有空格的文件,我找不到自动删除这些文件的方法,这些文件在 HDFS 中超过一定时间,因为有些文件的名称中有空格,删除时,例如,如果文件名为“hello word.csv”、“hello word2.csv”、“hello word2.csv”,它只会解释一行剩余的 hello。
hdfs dfs -rm /folder/hello
一个人给我的想法是删除最旧的 3 个月,首先将最近的 3 个月移动到一个临时文件夹,删除文件夹中剩余的所有内容,然后从该临时文件夹移动到原始文件夹。但是如果我想移动那些带有空格名称的文件,我会失败,因为带有空格的文件不会被移动。
有人有什么建议吗? 给我的想法是用具有这种特殊性的文件中的 _ 替换 hdfs 中的空格,但我想看看是否有人知道任何其他选项来删除它们而不进行更改名称的预处理。
我根本不了解 Hadoop,但我知道使用 bash 时,你不应该在不加双引号的情况下将变量(或命令替换)扩展为命令的参数;它很容易坏掉。
此外,处理文件路径很麻烦,因为它们可以包含任何字节,但
NUL
.
我不确定什么是完成任务的最佳方法,但
hdfs -stat
似乎比 hdfs -ls
更好的选择:
#!/bin/bash
folder_in=some/path
dias=30
hdfs dfs -stat '%Y %F %n/' "$folder_in"/* |
awk -v RS='/' -v folder="$folder_in" -v days="$dias" '
BEGIN {
mintime = (srand() ? srand() : srand()) - days * 86400
}
$2 == "file" && $1 < mintime {
sub(/^([^ ]* ){2}/,"");
printf("%s%c", folder "/" $0, 0)
}
' |
xargs -0 hdfs dfs -rm -f
注意事项:在
awk
中,$1
被用作数字,因此它的前导\n
字符被默默地忽略。
hdfs dfs -stat '%Y %F %n/' "$folder_in"/*
输出类似:
1391807842598 file File 1.txt/
1388041686026 directory someDir/
1388041686026 directory otherDir/
1391807875417 file File2.txt/
1391807842724 file File 3.txt/
由于我在末尾添加了一个
/
(不能出现在文件名中),awk
可以将其用作“记录分隔符”。
现在剩下要做的就是选择“inode时间”小于
time-of-day - N days
的文件并重建它们的完整路径,然后将它们输出为NUL
分隔列表(可以通过xargs -0
处理) .