【问题标题】:How can I replace the contents of all files in a directory with another file?如何用另一个文件替换目录中所有文件的内容?
【发布时间】:2012-02-28 04:59:03
【问题描述】:

我正在尝试编写一个简单的 bash 脚本,用新文件替换目录中的所有文件,但保留每个被替换文件的名称。

看起来这应该很容易,所以如果这很明显,我提前道歉。

【问题讨论】:

  • 您希望新文件中有什么内容 - 它们应该是空的吗?
  • 用什么替换每个文件?其他地方的副本?新内容?从哪里来?

标签: file bash replace


【解决方案1】:

由于您只想要新文件的内容但保持文件名相同,因此您可以使用cat 一步完成。

以下两个脚本以递归方式工作,并且可以使用任何文件名,即使是包含空格或换行符或其他任何可能在您尝试解析 ls 输出时中断的文件。

重击 > 2.x

#!/bin/bash
newFile="/path/to/newFile"
while IFS= read -r -d '' file; do
  cat "$newFile" > "$file"
done < <(find . -type f -print0)

重击 4.x

#!/bin/bash
newFile="/path/to/newFile"
shopt -s globstar
for file in **; do
  [[ -f "$file" ]] || continue
  cat "$newFile" > "$file"
done

【讨论】:

    【解决方案2】:
    #!/bin/sh
    for i in *; do
      if [ -f "${i}" ] ; then 
        cat /dev/null > "${i}";
      fi;
    done
    

    【讨论】:

    • 不要忘记引用你的变量,否则这会破坏有空格的文件。另外,他想用另一个文件替换内容,我假设它不是 /dev/null
    【解决方案3】:

    试试这个:

    for file in *; do
      if [ -f "$file" ] ; then
        > "$file"
      fi
    done
    

    【讨论】:

    • 这个答案比其他答案更好,因为它不会从 shell 派生外部进程来截断每个文件。
    • @Phil 但他不想截断文件,他想用另一个文件替换内容
    • @Phil 嗯,显然是这样。我把它放回去了,因为他的问题中没有任何暗示他希望文件被截断。
    【解决方案4】:

    如果您安装了 GNU Parallel:

    find . -type f -print0 | parallel -0 cat /path/to/foo \> {}
    

    如果你在一个只包含文件(没有目录)的目录中,那么这会更短,并且可能更容易记住:

    parallel cat /path/to/foo \> {} ::: *
    

    它可以正确处理包含空格、' 和 " 的文件(对于包含换行符的文件名,您需要上述内容)。

    您可以通过以下方式安装 GNU Parallel:

    wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
    chmod 755 parallel
    

    观看介绍视频以了解更多信息:http://pi.dk/1

    【讨论】:

      【解决方案5】:
      #!/bin/bash
      while read name; do
       cp "/directory/$name" /backup/
       mv /new/replacement "/directory/$name"
       echo "replaced /directory/$name with /new/replacement and stored backup in /backup"
      done <<< "$(ls -1 /directory/)"
      

      您可能会计划更改代码示例中的 /directory /backup 和 /new/replacement。 您可以使用“find”而不是“ls”来进行递归。 它现在不会有空间问题。

      【讨论】:

      • 这会中断包含空格的文件名。为什么不只是我们一个 glob 而不是在子 shell 中调用 ls
      • 请不要编辑其他人的答案来添加您自己的注释。这就是 cmets 的用途。请不要签署您的编辑;我们已经可以看到谁编辑了帖子。
      • 对不起,我必须给这个-1,因为你正在解析 ls 而不仅仅是使用 glob。请阅读this link为什么不惜一切代价避免解析ls
      • 在任何正常的现实世界目录中,这都可以正常工作,并且可以使用“查找”轻松扩展以进行递归替换。可以使用 glob 是对的,但是“从不使用 ls”文章会造成高度人为的问题。我已经添加了引号,所以“空格”不是问题。您应该更正您的示例,而不是对唯一真正的答案投反对票。您只阅读问题主题而不是阅读完整问题。他不想“零大小所有文件”他想“替换所有文件”
      • @John 1) 您没有通过在变量名称周围添加引号来修复脚本。问题是shell 对ls 的输出执行分词。它仍然会因带有空格的文件名而严重中断。我见过很多“真实世界的目录”,其中包含名称中带有空格的文件。当 shell 已经提供了不受此问题影响的 globbing nativity 时,为什么还要使用劣质的外部工具呢? 2)也许您将我的回答与其他人混淆了,但我也不是“所有文件大小为零”而是“替换所有文件”
      猜你喜欢
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 2018-07-21
      • 2016-10-18
      • 1970-01-01
      相关资源
      最近更新 更多