有没有办法从变量管道?

时间:2014-09-12 10:05:21

标签: bash shell

我试图查找文件结构中超过特定​​文件大小的所有文件,列出它们,然后删除它们。我现在的样子如下:

filesToDelete=$(find $find $1 -type f -size +$2k -ls)
if [ -n "$filesToDelete" ];then
echo "Deleting files..."
echo $filesToDelete
$filesToDelete | xargs rm
else 
echo "no files to delete"
fi

除了$ filesToDelete |之外,一切正常xargs rm,显然。有没有办法在变量上使用管道?还是有另一种方法可以做到这一点?我的google-fu并没有真正找到任何东西,所以任何帮助都会受到赞赏。

编辑:感谢大家的信息。我现在将在这里发布工作代码给其他任何绊倒这个问题的人:

if [ $(find $1 -type f -size +$2k | wc -l) -ge 1 ]; then
find $1 -type f -size +$2k -exec sh -c 'f={}; echo "deleting file $f"; rm $f' {} \;
else
echo "no files above" $2 "kb found"
fi

3 个答案:

答案 0 :(得分:4)

正如已经指出的那样,在这种情况下你不需要管道var。但是,如果你在其他情况下需要它,你可以使用

xargs rm <<< $filesToDelete

或更便携

echo $filesToDelete | xargs rm

小心文件名中的空格。

要同时输出该值并将其输出,请使用tee进行流程替换:

echo "$x" | tee >( xargs rm )

答案 1 :(得分:1)

你不需要做这一切。您可以直接使用find命令获取超过特定大小限制的文件,并使用xargs将其删除。

这应该有效:

#!/bin/bash
if [ $(find $1 -type f -size +$2k | wc -l) -eq 0 ]; then
    echo "No Files to delete"
else
    echo "Deleting the following files"
    find $1 -size +$2 -exec ls {} \+
    find $1 -size +$2 -exec ls {} \+ | xargs rm -f
    echo "Done"
fi

答案 2 :(得分:1)

您可以直接使用-execfind中找到的文件执行操作:

find $1 -type f -size +$2k -exec rm {} \;

-exec技巧使find执行为找到的每个匹配项指定的命令。要引用匹配本身,我们必须使用{} \;

如果您想要执行多项操作,-exec sh -c "..."可以执行此操作。例如,在这里您可以打印要删除的文件的名称...并删除它们。请注意存储文件名称的f={}内容,以便日后可以在echorm中使用:

find $1 -type f -size +$2k -exec sh -c 'f={}; echo "removing $f"; rm $f' {} \;

如果您想在未找到匹配项的情况下打印消息,可以使用wc -l计算匹配数(如果有),并使用if / else条件:

if [ $(find $1 -type f -size +$2k | wc -l) -ge 1 ]; then
   find $1 -type f -size +$2k -exec rm {} \;
else
   echo "no matches found"
fi

wc是执行w ord c次的命令(有关详细信息,请参阅man wc)。执行wc -l会计算l ines的数量。因此command | wc -l计算command返回的行数。

然后我们使用if [ $(command | wc -l) -ge 1 ]检查,进行整数比较:如果值为g reater或e qual to 1,则执行以下操作;否则,请执行else中的内容。


Buuuut之前的方法是使用find两次,这有点效率低下。当-exec sh -c打开子shell时,我们不能依赖变量来跟踪打开的文件数。为什么?因为子shell无法为其父shell分配值。

相反,让我们将已删除的文件存储到文件中,然后对其进行计数:

find . -name "*.txt" -exec sh -c 'f={}; echo "$f" >> /tmp/findtest; rm $f' {} \;
if [ -s /tmp/findtest ]; then #check if the file is empty
    echo "file has $(wc -l < /tmp/findtest) lines"
    # you can also `cat /tmp/findtest` here to show the deleted files
else
    echo "no matches"
fi

请注意,您可以cat /tmp/findtest查看已删除的文件,也可以单独使用echo "$f"(无重定向)来指示删除时。 rm /tmp/findtest也是一个选项,一旦完成该过程即可。