我正在尝试将目录中具有特定文件名的所有文件复制到另一个目录。但是,当我尝试打印文件名或复制文件时,文件名被打印为空白行/要复制的文件被视为空白。c 参数通过命令行传入。
我知道该参数有匹配项,那么为什么它被评估为空白?
代码:
#!/bin/bash
set -x
printf 'Processing option arguments:\n'
while getopts ":b:c:e:" arg; do
case "${arg}" in
b) b="$OPTARG"; echo "\$b is $b";;
c) c="$OPTARG"; echo "\$c is $c";;
e) e="$OPTARG"; echo "\$e is $e";;
esac
done
printf 'Done.\n\n'
shift $((OPTIND - 1))
printf 'Remaining (non-option) arguments:\n'
printf '%s\n' "$@"
cd "/opt/data"
ssh MyHost << EOF
rm -rf testDirectory
mkdir testDirectory
find . -type f -name '*$c*' -print0 | while IFS= read -r -d $'\0' file;
do
cp -r $file /testDirectory
done
EOF
输出:
cp: missing destination file operand after `/testDirectory'
Try `cp --help' for more information.
像这样调用脚本:
bash script.sh -b 06-30-20-18-10 -e 06-30-20-23-59 -c fileNameToMatch
编辑:我试图将文件名:
Test_07_24_18_09_53.log
解析为:1807180953
YearMonthDayHourMinute 格式
我该如何解析这样的日期?
我试图使用 SED,但它评估为空白:f=$(echo "$file" | sed 's/[a-zA-Z./]*//g')
>
month=$(echo "$f" | cut -d- -f1)
day=$(echo "$f" | cut -d- -f2)
year=$(echo "$f" | cut -d- -f3)
答案1
正如所提到的此评论,您使用了不带引号的EOF
,以便允许$c
在通过 ssh 传递到远程 shell 之前在本地 shell 中将其扩展为其值。还允许$file
(and $'\0'
- 但在任一 shell 中都会扩展为相同内容) 在本地进行扩展 - 假设它为空。由于您没有将其双引号括起来,因此复制命令变为
cp -r /testDirectory
因此/testDirectory
成为 cp 命令的来源参数,以及它的目的地不见了。
为了防止过早求值,$file
你可以使用反斜杠转义$
。你还应该用双引号括住扩展:
find . -type f -name '*$c*' -print0 | while IFS= read -r -d $'\0' file;
do
cp -r "\$file" /testDirectory
done
你可以还有反斜杠转义$'\0'
或简单地用空字符串替换它,''
这对于空分隔数据也同样有效。
-t DIRECTORY SOURCE
但是,使用 GNU cp 的格式可以更有效地避免远程 shell 循环:
find . -type f -name '*$c*' -exec cp -t /testDirectory {} +