在bash中从通配符中排除字符串

时间:2010-04-27 15:18:39

标签: bash

我正在尝试调整来自“Sams 24小时自学Linux”的bash脚本,这是一个名为rmv的安全删除命令。通过调用rmv -d file1 file2等删除文件。在原始脚本中,最多可以使用变量$ 1 $ 2 $ 3 $ 4删除4个文件。 我想通过使用通配符将其扩展为无限数量的文件。 所以我这样做:

for i in $*
do
mv $i $HOME/.trash
done

文件被删除没问题但是命令rmv -d的选项-d也被视为参数和bash对象,它们无法找到。有更好的方法吗?

谢谢, 彼得

#!/bin/bash
# rmv - a safe delete program
# uses a trash directory under your home directory
mkdir $HOME/.trash 2>/dev/null
# four internal script variables are defined
cmdlnopts=false
delete=false
empty=false
list=false
# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
  case "$cmdlnopts" in
    d ) /bin/echo "deleting: \c" $2 $3 $4 $5 ; delete=true ;;
    e ) /bin/echo "emptying the trash..." ; empty=true ;;
    h ) /bin/echo "safe file delete v1.0"
        /bin/echo "rmv -d[elete] -e[mpty] -h[elp] -l[ist] file1-4" ;;
    l ) /bin/echo "your .trash directory contains:" ; list=true ;;
  esac
done

if [ $delete = true ]
then
  for i in $* 
  do
  mv $i $HOME/.trash
  done
  /bin/echo "rmv finished."
fi
if [ $empty = true ]
then
  /bin/echo "empty the trash? \c"
  read answer
  case "$answer" in
    y) rm -i $HOME/.trash/* ;;
    n) /bin/echo "trashcan delete aborted." ;;
  esac
fi
if [ $list = true ]
then
  ls -l $HOME/.trash
fi

5 个答案:

答案 0 :(得分:0)

您可以在此处使用shift

一旦发现-dswitch中的一个选项,您就可以从位置参数中移除-d。接下来你可以

until [ -z $1 ] ; do
 mv $1 $HOME/.trash
 shift
done

答案 1 :(得分:0)

getoptsOPTIND设置为选项后第一个参数的索引。 (#

因此,在解析了您可以执行的选项之后:

shift $OPTIND-1

从参数列表中删除选项。

然后使用"$@"而不是$ *,您可以处理包含空格的文件。

答案 2 :(得分:0)

非常感谢!

我将代码更改为:

#!/bin/bash
# rmv - a safe delete program
# todo: add ability to handle wildcards
# uses a trash directory under your home directory
mkdir $HOME/.trash 2>/dev/null
# four internal script variables are defined
cmdlnopts=false
delete=false
empty=false
list=false
# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
  case "$cmdlnopts" in
    d ) echo -e "deleting: \n" "${@:2}" ; delete=true ;;
    e ) echo -e "emptying the trash..." ; empty=true ;;
    h ) echo -e "safe file delete v1.0"
        echo -e "rmv -d[elete] -e[mpty] -h[elp] -l[ist] file [...]" ;;
    l ) echo -e "your .trash directory contains:" ; list=true ;;
  esac
done
shift $OPTIND-1

if [ $delete = true ]
then
  for i in $@
  do
  mv $i $HOME/.trash
  done
  echo "rmv finished."
fi
then
  /bin/echo "empty the trash? \c"
  read answer
  case "$answer" in
    y) rm -i $HOME/.trash/* ;;
    n) /bin/echo "trashcan delete aborted." ;;
  esac
fi
if [ $list = true ]
then
  ls -l $HOME/.trash
fi

这会根据需要删除文件但我收到此错误:

/home/peter/rmv: line 21: shift: 2-1: numeric argument required
mv: invalid option -- 'd'
Try `mv --help' for more information.

答案 3 :(得分:0)

您需要使用

shift $(($OPTIND - 1))

去除进程命令行args。试试这个版本:

#!/bin/bash
# rmv - a safe delete program
# uses a trash directory under your home directory
mkdir -p $HOME/.trash 

# uses getopts command to look at command line for any options
while getopts "dehl" cmdlnopts; do
    case "$cmdlnopts" in
    d ) delete=true;;
    e ) echo "emptying the trash..." ; empty=true ;;
    h ) echo "safe file delete v1.0"
            echo "rmv -d[elete] -e[mpty] -h[elp] -l[ist] files" ;;
    l ) echo "your .trash directory contains:" ; list=true ;;
    esac
done

shift $(($OPTIND - 1))

if [ -n "${delete}" ]; then
    echo "deleting: " "${@}"
    mv ${@} $HOME/.trash
    echo "rmv finished."
fi

if [ -n "${empty}" ]; then
    read -p "empty the trash? " answer
    case "$answer" in
    y) rm -i $HOME/.trash/* ;;
    n) echo "trashcan delete aborted." ;;
    esac
fi

if [ -n "${list}" ]; then
    ls -l $HOME/.trash
fi

答案 4 :(得分:0)

晚会,但对于Google员工,这将产生彼得描述的错误:

shift $OPTIND-1

虽然Jurgen的回复中的语法不会:

shift $(($OPTIND-1))

问题是$ OPTIND-1被解释为一个字符串,而shift不能使用字符串作为参数。 $(())是Bash的arithmetic expansion operator。在其中放入一个字符串,该字符串被计算为算术表达式,并返回该值。