带通配符的BASH参数

带通配符的BASH参数,bash,parameters,wildcard,Bash,Parameters,Wildcard,我正在尝试执行一个bash脚本,该脚本将查找类似的文件并将其复制到目标目录 例如,我正在向脚本传递一个参数12300,我想复制所有以12300开头的文件。。。转到新目录 像这样: sh script.sh 12300 下面是脚本: if [ -f /home/user/bashTest/$@*.jpg ] then cp /home/user/bashTest/$@*.jpg /home/user/bashTest/final/ fi 这根本不管用。我尝试过各种各样的解决办法,但都不

我正在尝试执行一个bash脚本,该脚本将查找类似的文件并将其复制到目标目录

例如,我正在向脚本传递一个参数12300,我想复制所有以12300开头的文件。。。转到新目录

像这样:

sh script.sh 12300
下面是脚本:

if [ -f /home/user/bashTest/$@*.jpg ]
then
    cp /home/user/bashTest/$@*.jpg /home/user/bashTest/final/
fi
这根本不管用。我尝试过各种各样的解决办法,但都不管用。
问题是:如何在参数中使用通配符?

将扩展到
{}
中参数的东西括起来,即
/home/user/bashTest/${}*.jpg
。在您的情况下,应该使用
$1
而不是
$@
,因为您似乎只能处理给定给脚本的第一个参数
$1
扩展到第一个参数,
$2
扩展到第二个参数,以此类推

您还需要一个循环来迭代这个glob扩展到的所有文件,例如

for file in /tmp/${@}*.jpg
do
    if [ -f $file ]
    then
        echo $file
    fi
done

当您使用
-f
-e
检查多个文件时,可能会出现问题。我推荐。这有点像他会推荐的:

#! /bin/bash

ls -l /home/user/bashTest/$1*.jpg > /dev/null
if [ "$?" = "0" ]
then
    cp /home/user/bashTest/$1*.jpg /home/user/bashTest/final/
fi

不确定
$@
将如何在此处播放,或者是否需要。

在script.sh中编写此脚本:

cp/home/user/bashTest/$1*.jpg/home/user/bashTest/final/

就这些

UPD@macduff解决方案也很有用。

这里有一个解决方案:

#!/bin/bash    
cp /home/user/bashTest/${1}*.jpg /home/user/bashTest/final/
讨论
  • 在这种情况下,一个简单的
    cp
    命令就可以了
  • 我已经用嵌入空格的文件对它进行了测试

这将在$HOME目录和子目录中找到它们(您可能希望调整“查找”以跟随/不跟随符号链接和/或调整启动搜索的$HOME base目录)


首先,如果这是bash而不是bourneshell,请使用
bash
,而不是
sh
执行它。其次,阅读bash手册页,其中描述了“
特殊参数”
“想象一下如果有人运行
yourscript.sh;rm-rf”
,会发生什么。是的。我来看看。thanksIt不一定是bash。在不必要的情况下使用bashism编写代码只会限制可移植性,在本例中bashism甚至没有那么有用。另一方面,bash将运行sh代码,但不运行sh代码,因此如果确实包含bash或仅使用bash进行测试,请使用#/bin/bash在第一行。感谢您的帮助,但修改后仍然显示“[:4:/home/user/bashTest/40022.jpg:unexpected operator”脚本:如果[-f/home/user/bashTest/${1}*.jpg],那么cp/home/user/bashTest/${1}*.jpg/home/user/bashTest/final/fiSorry,它不起作用,因为您的glob扩展到多个文件名。我将编辑答案以将其考虑在内。感谢您的帮助。这起作用了。感谢您链接到kenfallon的博客:)
#!/bin/sh
DEST=/your/dest/folder

for FILE in `find "$HOME" -iname "$1"*`;do
  [ -f "$FILE" ] && mv "$FILE" "$DEST/$FILE"
  #or ln -s ...if you want to keep it in its original location
done

if you want to do multiple patterns using $@

for PATTERN in $@; do
for FILE in `find "$HOME" -iname "$PATTERN"*`;do
  [ -f "$FILE" ] && mv "$FILE" "$DEST/$FILE"
done
done