linux - 剪切-f 2- -d ""

标签 linux bash find cut

我经常调用以下脚本

清理.sh

#!/bin/bash
DEFAULT_LIMIT=10
INPUT=$1
PATTERN=$2
LIMIT=$3

if [ "$INPUT" == "" ] || [ "$PATTERN" == "" ]
then
        echo "usage: $0 INPUT PATTERN [LIMIT]"
        exit 1;
fi
if [ "$LIMIT" == "" ]
then
        LIMIT=$DEFAULT_LIMIT
fi

find /var/project/project1 -maxdepth 1 -type d -name "${INPUT}-${PATTERN}*" -printf '%T@ %p\n'|sort -nr|tail -n+$LIMIT|cut -f 2- -d " "|xargs -i rm -rf {}

所以这个应该从 /var/project/project1 很少出乎意料地(尽管非常重要)它会从 /var/project/project1 中删除预期目录以外的目录。知道为什么吗? cut 的行为是否为 2- 明确定义? f 和 field# 之间可以有空格吗?这不是故意写的,而是一个错误,但不太确定这段代码是否是导致意外删除的原因。

这很少可重现,因此不确定修复此问题 (cut -f2 -d "") 是否会解决我的问题

最佳答案

您当前的实现将在任何有空格的文件上中断。这就是 xargs 的本质,以及为什么它被认为是危险的,除非使用 -0(这在您当前的布局中是不可能的)。

例如,假设一个名为“foo bar”的文件进入xargsxargs 将像这样调用 rm:

rm -rf foo bar

它没有删除“foo bar”,而是删除了一个名为 foo 的文件和一个名为 bar 的文件。如果将剪切命令更改为 -f2 而不是 -f2-,它仍会在包含空格的文件上中断,但只会删除 foo .

这是一个处理所有可能文件名的例子:

#!/bin/bash
input=$1
pattern=$2
limit=${3:-10} # use 10 if $3 is not set

if [[ -z $input || -z $pattern ]]
then
        echo "usage: $0 INPUT PATTERN [LIMIT]"
        exit 1;
fi

dirs=()
while IFS= read -r -d '' latest # \0 is used as a delimiter, since it is not valid in a filename
do 
   dirs+=("$latest") # append files to the array in mtime sorted order, oldest first
done < <(find /var/project/project1 -maxdepth 1 -type d -name "${input}-${pattern}*" -printf '%T@ %p\0' | sort -zn)

dirs=("${dirs[@]#* }") # remove mtime from the elements
rm -rf "${dirs[@]:0:$limit}"

关于linux - 剪切-f 2- -d "",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12188970/

相关文章:

Linux - Grep 和进程替换

linux - 在 GNU/Linux 系统上,我应该从哪里加载应用程序数据?

我们可以在调用 pthread-create() 函数之前定义一个变量吗

unix - 如何使find返回hpux中符号链接(symbolic link)的目标?

c++ - Unordered_map 找到 const wchar_t*

linux - 即使使用 -k 选项,'nc' 命令也会停止

linux - 管道中失败的命令未触发 "catch"命令

linux - 为什么这个 'syntax error' 在 'else' 之前?

linux - 使用 bash 脚本在现有 screen session 中通过 Enter 键传递命令

xcode - 键盘快捷键,用于在Xcode 4中查找当前选定的文本