【问题标题】:Creating a file in a directory other than root using bash使用 bash 在 root 以外的目录中创建文件
【发布时间】:2016-04-12 11:26:15
【问题描述】:

我目前正在为一个班级项目编写一个自动评分脚本。它必须能够搜索任意数量的给定目录让我们说 例如

usr/autograder/jdoe/

jdoe 包含两个文件 house.c 和 readme.txt。

我需要在 jdoe 中创建一个名为 jdoe.pdf 的文件

目前我正在使用下面的这行代码来获取我需要创建文件的路径。其中 $1 是用户输入的路径,其中包含自动评分器将评分的项目。

find $1 -name "*.txt" -exec sh -c "dirname {}" 

当我尝试将 /somename.pdf 添加到此语句的末尾时,我得到 readme.txt/somename.pdf

与另一个 -exec 一起获取文件的名称。

\; -exec sh -c "dirname {} xargs -n 1 basename" \;

我在将这两者合并为一个工作语句时遇到了问题。 我是 unix 编程的新手,如果这意味着使用不同的 unix 工具重新编写代码,我将不胜感激任何建议或帮助。

这里的主要问题是如何在我调用脚本的目录以外的路径中创建文件。提前致谢。

【问题讨论】:

  • 您是否只是想使用find 命令生成所有somename.pdf 文件的路径?或者你想在这里做更多的事情?
  • @Etan Reisner 我正在尝试使用 find 来查找路径并在每个路径中创建一个名为 somename.pdf 的文件。对不起,如果我不清楚。

标签: linux bash shell unix


【解决方案1】:

这个怎么样?

find  "$1" -name "*.txt" -exec bash -c 'd=$(dirname "$1"); touch $d"/"$(basename "$d").pdf' - {} \;

【讨论】:

  • 太棒了!这就是我之前尝试做的事情,我的一些语法被关闭了。唯一的事情是当前来自您的代码的 pdf 的名称是一个目录。我在代码的第二部分添加了“dirname {} | xargs -n 1 basename”,这正是我所需要的!非常感谢!
  • 将参数内的{} 扩展为sh -c/bash -c非常不安全的。 find 无法正确引用该用法。您需要将其作为参数传递给脚本并使用位置参数以确保安全bash -c 'd=$(dirname "$1"); ...' - {}
【解决方案2】:

您可以使用更改目录命令 (cd) 在另一个路径中创建文件。

如果您在 usr/autograder/script 中启动脚本并希望更改为 usr/autograder/jdoe,您可以使用 shell 命令 cd ../jdoe(相对)或 cd usr/autograder/jdoe(绝对)更改目录。

现在您在 usr/autograder/jdoe 目录下,您可以在此目录中创建文件,例如gedit readme.txt 将打开 gedit 并在 usr/autograder/jdoe 中创建文件。

【讨论】:

  • 感谢米奇的快速回复。你的回复很有道理。我需要做绝对,因为由于多个学生,我在不同的目录之间跳来跳去。不过,我确实有一个后续问题。如何将信息从代码的“sh -c dirname”部分传输到 cd?我一直对如何使用我得到的数据感到困惑。
  • 如果你想合并两个语句,你可以使用“&&”。例如:你在你的主目录(~)中,你想切换到桌面并用 gedit 打开一个文件,你可以使用:“cd Desktop/ && gedit readme.txt” 现在你不需要写“gedit Desktop/ readme.txt”,因为您在 Desktop 目录中进行了更改。此命令将更改目录并一步打开 gedit。
【解决方案3】:

最简单的方法是遍历find返回的文件,然后做任何你需要做的事情。

例如:

find "$1" -type f -name "*.txt" -print0 | while IFS= read -r -d $'\0' filename; do
    dir=$(dirname "$filename")

    # create pdf file
    touch "$dir/${dir##*/}.pdf"
done

(注意使用find -print0 来正确处理包含空格和换行符的文件名。)

【讨论】:

    【解决方案4】:

    这是你要找的吗?

    function process_file { 
        dir=$(dirname "$1")
        name=$(basename "$1")
        echo name is $name and dir is $dir; 
        cd "$dir"
        touch "${dir##*/}.pdf" # or anything else
    }
    
    # export the function, so that it is known in the child processes
    export -f process_file 
    
    find . -name '*.txt' -exec bash -c "process_file '{}'" \;
    

    【讨论】:

      猜你喜欢
      • 2012-01-13
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      相关资源
      最近更新 更多