【问题标题】:Bash: Delete until a specific fileBash:删除直到特定文件
【发布时间】:2009-06-15 17:21:02
【问题描述】:

嘿, 假设您在一个文件夹中有许多文件,并且您希望首先按字母顺序对其进行排序,然后删除所有文件,直到一个特定文件(不包括它)。

所以我正在搜索一个函数/命令/脚本/任何将一个字符串作为输入的函数/命令/脚本/任何内容,并删除该文件之前的所有文件。

我想到了一个简单的 bash 脚本:

for i in *; do
   if [ "$i" == "input" ]; then
      break;
   fi
   rm "$i"
 done 

但这是一个相当长的解决方案,由于未指定排序,因此无法按预期工作。没有更短的吗?

谢谢

【问题讨论】:

  • 有人刚刚告诉我“*”已经对其输入进行了排序。如果这是真的,你的东西应该可以正常工作。
  • @litb - 已确认。在路径名扩展部分下的 bash 手册页中,它使用了短语“按字母顺序排序的列表”。

标签: bash


【解决方案1】:
rm `ls |sed '/pattern/,$d'`

ls 输出默认按字母顺序排序。

将模式替换为与要删除的文件之后的第一个文件匹配的正则表达式。除非有什么花哨的事情,否则模式可以只是要停止删除的文件的名称。或者使用“^filename$”来确定模式。

一如既往,先测试再做。例如,在开头添加“echo”以打印将要执行的操作。

echo rm `ls |sed '/pattern/,$d'`

【讨论】:

  • 关于解析 ls 输出的有趣文章。如果您有机会获得如此疯狂的文件名或在面对不可信的输入(目录内容)时需要安全性,请考虑到这一点。总的来说,这似乎是一个很难接受的建议。
  • 如果你想替换ls 来获取文件列表(我猜你会想跳过rm 的目录名)。使用,find . -type f
  • 这与“从不解析”点有何关系?它也适用于查找输出,不是吗?似乎 find 正在抓挠不同的痒 - 对递归的渴望与当前的目录。
  • @John M:find 的输出是可靠的并且可以被解析。 ls 的输出是“只有眼睛”。阅读我在上面的评论中引用的页面。
【解决方案2】:

试试,

rm $(ls | sort | sed '/input/,$d')

首先尝试不使用rm 作为,

ls | sort | sed '/input/,$d'

在这里,input 是您用于捕获文件名的正则表达式。请记住,第一场比赛之后的一切都会过去!

【讨论】:

  • 管道 ls 会导致转义字符和分词问题。 (我认为这不适用于文件名中的空格)
  • #Rob,ls 和 sort 很明显,sed 搜索输入正则表达式并从匹配 (,) 的第一行开始删除 (d) 直到文件末尾 ($)。剩下的到达标准输出。
【解决方案3】:

这似乎有效($i 是要删除的文件名)

find . -maxdepth 1 -type f | sort | 
    while read -r line && [[ $line < $i ]]; do 
        echo $line
    done

如果你确定它做你想要的,用

替换 echo 命令
rm "$line"

Never pipe ls for processing things。 ls 不是为该任务而设计的。使用路径名扩展或find 等工具。

示例失败案例:

$ echo > 'I have fun.mp3'
$ cat $(ls | grep 'have fun')
cat: I: No such file or directory
cat: have: No such file or directory
cat: fun.mp3: No such file or directory

它将$(...) 的结果拆分为单词并将这些单词作为单独的参数传递。因此, rm 不会将这样的名称视为一个整体,而是将其拆分为单词。

路径名扩展是在分词之后完成的,所以分词不再影响其结果。这就是为什么cat * 将正确处理空格(或为此目的,IFS 变量中的任何其他字符)。

【讨论】:

    【解决方案4】:

    如果要排序:

    for i in `ls | sort`
    do
        if [ "$i" == "input" ]
        then
            break
        fi
        rm "$i"
    done
    

    当然,这可以缩短,但这个解决方案可能是最简单和最易读的(通常最重要)。这确实现在可以正确处理带有空格的文件了。

    【讨论】:

    • 如果文件名包含空格会导致错误。我知道这可以通过“ls | sort | while read line;”来解决。但它使代码更长。还是谢谢!
    • 哦,是的,我忘记了空格问题...如果您添加引号,它仍然有效(至少在我的机器上)。
    • 带 * 的路径名扩展已经排序。 "而且不要解析 ls。"
    猜你喜欢
    • 2018-08-31
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多