cut -f 2- -d“”

时间:2012-08-30 02:08:52

标签: linux bash find cut

我有以下经常调用的脚本

cleanup.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 {}

所以这个应该从$LIMIT删除前缀为$INPUT-$PATTERN的{​​{1}}目录,并且很少出乎意料地(尽管非常关键)删除目标以外的目录。 /var/project/project1。知道为什么吗?切割的行为是否定义为2-?我们可以在f和场之间有空格#?这不是故意写的,而是一个错误,但不太确定这段代码是否是造成这种意外删除的代码。

这很难重现,因此不确定修复此问题(/var/project/project1)是否能解决我的问题

2 个答案:

答案 0 :(得分:3)

您当前的实现将在具有空格的任何文件上中断。这是xargs的性质,以及除非使用-0(在当前布局中无法实现),否则它被认为是危险的。

作为一个例子,假设一个文件使其成为xargs,称为“foo bar”。 xargs会像这样调用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}"

答案 1 :(得分:0)

请注意,即使我们要求第二个字段,echo "one" | cut -f 2 -d " "也会显示“一个”。

那么当你打电话给cut -f 2- -d " "并且只有一个领域时,你会怎么想?如果没有,则添加-s选项。

换句话说改变

cut -f 2- -d " "

cut -s -f 2- -d " "

希望它有所帮助。