【问题标题】:Using bash script to move folders based on their name使用 bash 脚本根据文件夹名称移动文件夹
【发布时间】:2021-12-26 18:26:00
【问题描述】:

我有一个包含目录列表的文件 (list.txt),我想读取每一行,然后根据目录名称中的数字范围将文件夹移动到特定的目标文件夹。无论文件中列出多少个目录,它都需要工作,因为这每天都会改变。

在 list.txt 中,每一行都像这样列出目录;

/20211601_113212_hello_LGD_text.csv/KLS_8938I1_02020721_1/

我只对粗体文本感兴趣,如果该数字在某个范围内,例如1-500 我想把它移到'folder1',或者500-100'folder2'等等。该数字将始终位于 _1/ 之前,并且始终为 4 个数字。

使用

grep -0 '......$' /list.txt | cut -d_ -f1

我已经成功地 grep 了我想要的号码,但我无法对这些信息做任何事情。我想我可以将每一行拆分为单独的文件,然后使用 for 循环遍历每个文件,但我不知道这将如何工作。有什么建议吗?

【问题讨论】:

  • 你试过使用bash的conditional expressions吗?要比较数字,请参阅以 arg1 OP arg2 开头的最后一部分

标签: linux bash grep find xargs


【解决方案1】:
declare -i number
while IFS= read -r directory; do
  ((number = 10#"${directory: -7:-3}"))
  echo mv "${directory%/}" "folder$(((number + 499) / 500))/"
done < list.txt
  • 上述故障突出显示的语法,# 在这种情况下不是评论的开头。
  • for-cycle 读取整行时不会弄乱空格,也不会考虑反斜杠转义。这是为了确保目录名称可以(几乎)是任意的。
  • 我们通过从末尾的第 7 个字符开始并在末尾的第 3 个字符之前结束来提取数字(均从 1 开始)。或者,_1/ 也可以使用 ${directory%_1/} 剥离。
  • 我们将数字视为整数 (declare -i) 并确保它 被解释为八进制数 (10#),否则以 0 开头的整数文字是八进制(例如$((08)) 产生错误)。
  • 我们生成 mv 命令 - 一旦对输出满意就删除 echo - 其中 ${directory%/} 删除最后的斜线(您可能需要调整),然后 $(((number + 499) / 500))生成所需的基于 1 的“文件夹”编号,例如499 产生 1500 产生(仍然)1501 产生 2 等。您需要根据自己的喜好进行调整。

【讨论】:

  • 不错!为什么要去掉最后的斜线并在folder_N/ 的末尾添加一个?根据 OP 规范,folder 和数字之间没有下划线。
  • @RenaudPacalet 下划线很好;编辑。至于最后的斜线,有一些工具(mv 除外),其中最后的斜线表示“移动目录的内容”而不是整个目录。所以我通常倾向于在任何地方避免最后的斜线,不管它是否重要。
  • 我明白了。另一方面,如果不小心是文件而不是目录,则会出现错误而不是静默文件移动。所以源名称中的最后一个斜线可以被认为是一种安全措施。
  • @RenaudPacalet 实际上,文件的一个更大问题是名称被破坏(没有最后一个字符)。所以我把它编辑为${directory%/},如果有斜线,它只会去掉斜线。否则,我认为可以安全地假设,根据问题,list.txt 中只会列出目录。但无论如何,如果斜线实际上丢失了,替换 ${directory: -7:-3} 也会中断。我猜,让 that 更有弹性会使答案过于复杂。
  • 非常好,谢谢@AndrejPodzimek。通过对文件夹名称进行一些调整,这正是我所需要的。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多