【问题标题】:Moving a file and renaming it after the directory which contains it on Bash移动文件并在 Bash 上包含它的目录之后重命名它
【发布时间】:2017-11-13 07:06:23
【问题描述】:

我正在尝试在 Linux 上学习 bash,只是为了好玩。我认为拥有一个将相似文件组合在一起的 .sh 会非常有用。例如,假设我们有目录

/home/docs/

在目录中,我们有 /mathdocs/、/codingdocs/ 等。

在这些子目录中,我们都有 doc.txt,在所有这些子目录中。子目录中所有文件的名称相同。

假设我想将它们组合在一起,并且我想将所有文件移动到 /home/allthedocs/ 并在它们所在的目录之后重命名它们。(mathdocs.txt、codingdocs.txt 等)

我该怎么做?

我尝试创建基于 ls 和 cp 命令的脚本,但我不知道如何在移动目录后使用目录名称重命名其中的文件。我想它必须是某种迭代语句(对于 Y 目录上的 X),但我不知道该怎么做。

【问题讨论】:

标签: linux bash


【解决方案1】:

您可以使用 mv 一次性移动和重命名您的文件,并通过一个循环来通过一个 glob 抓取您的所有文件:

#!/bin/bash

dest_dir=/home/allthedocs

cd /home/docs
for file in */doc.txt; do
  [[ -f "$file" ]] || continue # skip if not a regular file
  dir="${file%/*}"             # get the dir name from path
  mv "$file" "$dest_dir/$dir.txt"
done

查看这篇文章了解更多信息:

【讨论】:

  • 应该将“shopt -s globstar”包含在 .bashrc 中,还是按原样工作?
  • 这可以在没有设置globstar 的情况下工作,因为我们只处理一级目录。
【解决方案2】:

这是一种处理文件名中的空格的单行解决方案,就像 @codeforester 的解决方案处理 glob 一样。

请注意,空格会通过传递给“find”的“-print0”选项、while 循环中的内部字段分隔符 (IFS) 以及 file3 变量的引号来处理。

从file2到file3的参数替换去掉了前导的“./”。

move命令中的参数替换将路径变成文件名(在/home/docs/下运行):

find . -maxdepth 2 -mindepth 2 -print0 | while IFS= read -r -d '' file; \
do file2=$(printf '%s\n' "$file"); file3=${file2#*\/*}; \
mv "$file2" ../allsil/"${file3//\//}"; done

【讨论】:

  • 基于 glob 的解决方案适用于带有空格的文件。 find 并不是真正需要的,因为目录层次结构和文件名 (doc.txt) 都是固定的。
猜你喜欢
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-05-31
  • 1970-01-01
  • 2022-11-18
  • 2021-06-05
相关资源
最近更新 更多