【问题标题】:UNIX command - clear files based on the date logicUNIX 命令 - 根据日期逻辑清除文件
【发布时间】:2021-10-30 06:35:04
【问题描述】:

--UNIX 新手--

我正在寻找一个 UNIX 命令来根据日期逻辑删除目录中的一些文件。示例文件结构:

Aug 30 01:30 Test20210830.ctl
Aug 30 01:30 Test20210830.txt
Aug  3 01:30 Test20210803.ctl
Aug  3 01:30 Test20210803.txt
Aug  2 01:30 Test20210802.ctl
Aug  2 01:30 Test20210802.txt
Aug  1 01:30 Test20210801.ctl
Aug  1 01:30 Test20210801.txt
Jul  1 01:30 Test20210701.ctl
Jul  1 01:30 Test20210701.txt
Jun 16 01:30 Test20210616.ctl
Jun 16 01:30 Test20210616.txt
Jun 15 01:30 Test20210615.ctl
Jun 15 01:30 Test20210615.txt

ls -ltr 测试* | grep date +%b | head -2 -- 这个命令给出了我想要保留的前 2 个文件(每个月的前 2 个文件)。 我想从同一个月删除其余文件(因此 7 月和 6 月 2 日的文件仍然必须存在)。有一个工作在每个月底运行,所以..

删除文件并保留我想要的文件的最佳方法是什么?

【问题讨论】:

  • 我建议使用文件名中的日期对它们进行排序,因为它是简单的字典顺序
  • 如何在脚本或命令中做到这一点?如果我想删除其余的文件?
  • 请准确显示您要保留的文件
  • 我有个主意。我会准备一个答案

标签: shell unix


【解决方案1】:

我已将您提供的输入放入名为 input 的文件中。

此代码可以安全运行,因为它实际上并没有删除文件,但您可以自己查看输出。它会告诉您哪些文件将被删除,哪些文件将在每个部分的末尾保留一些不言自明的行。

它只计算到目前为止该月出现的次数,如果超过两次,则输出removing file。否则打印file stays!

输出附在下面。

lastmon=""
counter=0

# replace "cat input" with your "ls -l" or so
cat input | egrep -o "\S+$" | sort -r | # extract filenames
  for filename in $(cat)
  do
    # extract pieces from filename
    echo "filename: $filename"
    echo -n "date: "
    echo $filename | egrep -o '[0-9]+'
    echo -n "month: "
    echo $filename | egrep -o '[0-9]+' | cut -b5-6 
    
    # compare month to last month
    mon="$(echo $filename | egrep -o '[0-9]+' | cut -b5-6)"
    if [ "x$mon" != "x$lastmon" ]
    then counter=0
    fi
    lastmon="$mon"
    
    # keep counting
    counter=$((counter+1))
    echo counter: $counter 

    # if more than two in a row decide to remove file
    if [ $counter -gt 2 ]
    then echo result: removing file
    else echo result: file stays!
    fi
    
    echo # print empty line
  done

输出

filename: Test20210830.txt                                                                                                                                                                                                                                                         [39/1872]
date: 20210830                                                         
month: 08                                                              
counter: 1                                                             
file stays!                                                            
                                                                       
filename: Test20210830.ctl                                             
date: 20210830                                                         
month: 08                                                              
counter: 2                                                             
file stays!                                                            
                                                                       
filename: Test20210803.txt                                             
date: 20210803                                                         
month: 08                                                              
counter: 3                                                             
removing file                                                          
                                                                       
filename: Test20210803.ctl                                             
date: 20210803                                                         
month: 08                                                              
counter: 4                                                             
removing file                                                          
                                                                       
filename: Test20210802.txt                                             
date: 20210802                                                         
month: 08                                                              
counter: 5                                                             
removing file                                                          
                                                                       
filename: Test20210802.ctl                                             
date: 20210802                                                         
month: 08                                                              
counter: 6                                                             
removing file                                                          
                                                                       
filename: Test20210801.txt                                             
date: 20210801                                                         
month: 08                                                              
counter: 7                                                             
removing file                                                          

filename: Test20210801.ctl                                             
date: 20210801                                                         
month: 08                                                              
counter: 8                                                             
removing file       

filename: Test20210701.txt                                             
date: 20210701                                                         
month: 07                                                              
counter: 1                                                             
file stays!                                                            

filename: Test20210701.ctl                                             
date: 20210701                                                         
month: 07                                                              
counter: 2                                                             
file stays!                                                            

filename: Test20210616.txt                                             
date: 20210616                                                         
month: 06                                                              
counter: 1                                                             
file stays!                                                            

filename: Test20210616.ctl                                             
date: 20210616                                                         
month: 06                                                              
counter: 2                                                             
file stays!                                                            

filename: Test20210615.txt                                             
date: 20210615                                                         
month: 06                                                              
counter: 3                                                             
removing file                                                          

filename: Test20210615.ctl                                             
date: 20210615                                                         
month: 06                                                              
counter: 4                                                             
removing file                                                          

【讨论】:

    【解决方案2】:

    如果您只想保留每个月的前两个按字典顺序排序的文件名称,您可以使用简单的循环和 shell 文件名扩展:

    for year in 2021
    do
      for month in {01..12}
      do
        set -- Test${year}${month}*
        if [ "$#" -gt 2 ]
        then
          shift 2
          echo would rm -- "$@"
        fi
      done
    done
    

    请注意,这将删除 Test20210616.ctlTest20210616.txt,因为它专门移除了每个月的前 两个 文件名。

    此脚本的核心部分位于setshift 2 部分。 set -- Test${year}${month}* 行扩展了年份和月份变量,并附加了* 通配符以匹配以“Test”开头的任何/所有文件名,后跟循环的当前年份和月份值。一旦这些文件名被扩展 - 或不! -- 它们在特殊的$@ 数组变量中可用。请注意,如果没有匹配项,则数组中将有一个值——未扩展的“测试”...通配符。如果我们需要知道是否有一个 实际 文件名匹配,这 是一个需要注意的特殊情况,但这里我们只对存在的情况感兴趣多于两场比赛。结果文件名(如果有)将按字典顺序添加到数组中。

    一旦文件名在$@ 中,shift 2 就会简单地将前两个元素从列表的前面弹出——这里是前两个文件名(按字典顺序排序)。剩下的是一个或多个候选文件名将被删除。

    如果结果看起来正确,请删除 echo would 以启用此功能。

    【讨论】:

    • 介意解释一下命令吗?对于每个只需添加描述它的作用?这部分具体: set -- Test${year}${month}* if [ "$#" -gt 2 ] then shift 2 echo will rm -- "$@"
    • 所以如果我不想在这个逻辑中使用年份,我可以删除年份部分并保留月份吗?像这样:for month in {01..12} do set -- Test*${month}* if [ "$#" -gt 2 ] then shift 2 echo will rm -- "$@" fi done跨度>
    • 我想您可以删除年份,但问题中的文件名包含年份,所以我将它们包含在答案中。
    • 是的,对.. 我希望他们每年都被替换,这就是为什么我会玩这个脚本 - 会尝试更新!
    猜你喜欢
    • 1970-01-01
    • 2015-09-20
    • 2013-03-24
    • 2019-08-04
    • 2023-04-04
    • 1970-01-01
    • 2022-01-17
    • 2011-07-30
    • 2013-01-20
    相关资源
    最近更新 更多