Bash脚本错误“;awk fatal无法打开文件进行读取(没有此类文件或目录)”;

Bash脚本错误“;awk fatal无法打开文件进行读取(没有此类文件或目录)”;,bash,find,Bash,Find,我正在尝试创建一个bash脚本,该脚本将查找特定目录中的所有文本文件,读取其内容,其标准格式为: country: United Kingdom district: Greater London town: Acton 然后将“:”后面的数据发布到具有相应列名的数据库中 以下是我目前掌握的代码: #!/bin/bash notdone="/a/dir/notdone" done="/a/dir/done" tempfile="/tmp/$$.s

我正在尝试创建一个bash脚本,该脚本将查找特定目录中的所有文本文件,读取其内容,其标准格式为:

country: United Kingdom
district: Greater London
town: Acton
然后将“:”后面的数据发布到具有相应列名的数据库中

以下是我目前掌握的代码:

#!/bin/bash
notdone="/a/dir/notdone"
done="/a/dir/done"
tempfile="/tmp/$$.sql"

trap 'rm -f ${tempfile}' EXIT INT

find -- ${notdone}/*.txt | while read -r filename
do

    country=$(awk -F":" '/^country/ { print $2 }' ${notdone}/${filename})
    district=$(awk -F":" '/^district/ { print $2 }' ${notdone}/${filename})
    town=$(awk -F":" '/^town/ { print $2 }' ${notdone}/${filename})

    echo "INSERT INTO some_table (country,district,town) VALUES(\"${country}\",\"${district}\",\"${town}\")" > ${tempfile}
    
    mysql --user=some_user --password=some_pass some_table < ${tempfile} || {

        echo "Error while processing file: ${notdone}/${filename}"

        break

    }

    mv ${notdone}/${filename} ${done}/

done
以及:


我确信我缺少一些东西来完成bash当前使用的目录和传递给awk的名称,但我无法理解,因为我对脚本做了所有更改。

修复并改进了您的脚本

#/usr/bin/env bash
basedir=“$HOME/t”
notdonedir=“$basedir/notdone”
donedir=“$basedir/done”
#声明二进制标志
declare-a flags=(HAS_国家HAS_地区HAS_城镇)
对于“${!flags[@]}”中的位;做

declare-ri“${flags[bit]}”=$((1脚本使用“find”生成文件名列表。每个文件名将包含完整路径(/a/dir/notdone/filename.txt),因此无需在awk/mv命令中再次为文件名加前缀:

    country=$(awk -F":" '/^country/ { print $2 }' "${filename}")
    district=$(awk -F":" '/^district/ { print $2 }' "${filename}")
    town=$(awk -F":" '/^town/ { print $2 }' "${filename}")

    ...
    mv "${filename}" ${done}/

诚然,这并不能解释错误消息。但它可能会解决问题。

您收到的错误消息非常清楚,没有这样的文件或目录。可能如果删除初始斜杠,则文件路径存在?我最初尝试过,但脚本开始搜索根目录并遍历所有文件夹s表示所有内容。
find
返回
的文件名,而read-r filename
带有路径,您在
${filename}
前面加上
$(awk…${notdone}/${filename})中的另一个路径
在删除初始斜杠时遇到了一点小问题,我的Web服务器根目录的内容都被移动到了/done文件夹^ ^。吸取了教训。我一直在尝试使用
-printf“%f\n”
命令,但我还没有完全理解它。我将通过
手册找到
文档并开始学习使用它。@EdMorton感谢您的注意。这实际上非常有效,我很遗憾我最初没有注意到这一点。感谢修订和改进的代码。我已经测试过它,并且有一个问题。当txt文件在ly包含3行,最后一个值抛出与错误输入相关的错误,在本例中为“town”。如果我在txt文件中添加第四行,一切正常。这是因为If/then语句吗?@MeltingCube当最后一行没有换行结束时,
读取
返回false,而
则返回false循环在不处理值的情况下过早退出。我修复了脚本以处理这种情况:
而IFS=':'read-r-d$'\n'key-value | |[“$key”]
,因此,如果
读取
失败是因为行结束之前文件结束,它会检查
$key
变量中是否读取了某些内容,如果是,则继续进入
while
循环。感谢您,它工作得非常好。除了解决方案之外,我还可以找到解决相同问题的另一种方法o我可以扩展我的工作方式。@MeltingCube将脚本更新为字段acquisitionOK的二进制标志,因此我刚刚完成了对上一版本中的
if
语句的轻微修改,以考虑到并非所有三个值都存在,而是country+district或country+town的组合,使用
if[-n“$country”&&n“$district”]| |[[-n“$country”&&n“$town”]];然后
。如何将其应用于上述版本的代码?我尝试更改
while
if
语句,但无法实现我想要的。这与声明有关吗?标记已定义,因此我认为可以在
if
语句中单独引用它们。
mv: cannot stat ‘/a/dir/notdone/test.txt’: No such file or directory
    country=$(awk -F":" '/^country/ { print $2 }' "${filename}")
    district=$(awk -F":" '/^district/ { print $2 }' "${filename}")
    town=$(awk -F":" '/^town/ { print $2 }' "${filename}")

    ...
    mv "${filename}" ${done}/