Bash

根據文件名中的日期將文件分類到文件夾中?

  • May 23, 2018

已解決:查看評論中的更新。

我正在嘗試根據該日期將文件名中帶有日期的文件排序到文件夾中。這些文件過去在文件名中有一個空格,就像這樣。有一些舊文件,所以我也需要對它們進行排序。

發傳真_20180521121901.pdf

我們現在正在獲取文件名中沒有空格的文件,所以它只是 Dispatch_20180521124202.pdf

日期是 20180521,其餘的我認為是消息 ID,但我們不需要。只是日期。

對 bash 腳本(ubuntu 18.04 框)的這種嘗試最終創建了一個名為 2018-05-21 的單個文件夾,該文件夾位於文件所在目錄的上一級,並將所有 pdf 文件放在該文件夾中。

   for x in /home/tb/temp/*.pdf
do
   d=$(date -r "$x" +%Y-%m-%d)
   mkdir -p "$d"
   mv -- "$x" "$d/"
done

這最終以某種方式移動到了一個名為“e”的文件夾中。

for x in /home/tb/temp/*.pdf
do
   d="${x:4:4}-${x:8:2}-${x:10:2}"
   mkdir -p "$d"
   mv -- "$x" "$d/"
done

這種嘗試?我最終為每個 PDF 建立了一個文件夾。

/home/tb/20180521124202.pdf/Dispatch Fax_20180521124202.pdf /home/tb/20180521121901.pdf/Dispatch Fax_20180521121901.pdf

for x in /home/tb/temp/*.pdf
do
   d=$(echo "$x" | awk -F _ '{print $2}')
   mkdir -p "$d"
   mv -- "$x" "$d/"
done

這些腳本來自以前的文章herehere以及那些為他們工作的文章,但即使目標相同,我也沒有同樣的運氣。

我的目標是最終從 rsync 填充一個臨時目錄(從另一台伺服器提取這些文件),然後通過 cron,執行此腳本以根據日期將內容移動到文件夾中,並通過啟用“選項 +索引”的 Apache 提供該目錄。這是一個僅限 Intranet 的頁面,並且這台特定的機器沒有外部訪問權限。目錄結構簡單。最終類似於 /var/www/html/2018/5/21 等,遵循 YYYY/MM/DD 格式。

我只是不知道如何讓它工作,而且我對 bash 腳本的了解非常生疏。我查看了其他幾個類似的範例,後來我發現它不適用於文件名中包含空格的文件。

我對想法持開放態度!

你的問題對我來說並不完全清楚,但我想我可能明白你想要做什麼。

這是您正在使用的循環:

for x in /home/tb/temp/*.pdf
do
   d="${x:4:4}-${x:8:2}-${x:10:2}"
   mkdir -p "$d"
   mv -- "$x" "$d/"
done

您提供的範例文件名是:

  1. Dispatch Fax_20180521121901.pdf
  2. Dispatch_20180521124202.pdf

我突然想到的一個問題是您的參數替換錶達式 ( d="${x:4:4}-${x:8:2}-${x:10:2}") 似乎沒有產生正確的結果,例如:

> x='Dispatch Fax_20180521121901.pdf'
> d="${x:4:4}-${x:8:2}-${x:10:2}"
> echo ${d}
atch- F-ax

> x='Dispatch_20180521124202.pdf'
> d="${x:4:4}-${x:8:2}-${x:10:2}"
> echo ${d}
atch-_2-01

您可以嘗試grep改用,例如:

> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> echo ${d}
20180521

> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> echo ${d}
20180521

或者,如果您想添加連字元,您可以使用以下sed基於 - 的命令替換:

> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
> echo ${d}
2018-05-21

> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
> echo ${d}
2018-05-21

假設這是所需的結果(即您想要表單的子目錄%Y-%m-%d),我們可以將您的參數替換錶達式替換為grep基於 - 的命令替換。這將為我們提供以下修改後的循環:

for filename in /home/tb/temp/*.pdf; do
   datestring=$(echo "${filename}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
   mkdir -p "${datestring}"
   mv -i -- "${filename}" "${datestring}/"
done

這應該生成表單的子目錄%Y-%m-%d並用適當的文件填充它們。


**更新:**根據您的評論,聽起來您想要的是表單的嵌套子目錄%Y/%m/%d。為此,您需要分別提取年、月和日子字元串,例如:

> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> year=${d:0:4}
> month=${d:4:2}
> day=${d:6:2}
> echo "${year}/${month}/${day}/"
2018/05/21/

這導致我們進入以下循環:

for filename in /home/tb/temp/*.pdf; do
   datestring=$(echo "${filename}" | grep -Po '\d{8}')
   year=${datestring:0:4}
   month=${datestring:4:2}
   day=${datestring:6:2}
   directory="${year}/${month}/${day}/"
   mkdir -p "${directory}"
   mv -i -- "${filename}" "${directory}"
done

引用自:https://unix.stackexchange.com/questions/445212