我不断收到此错误
line 3: Syntax error near unexpected token `|'
这是目前的脚本:
for filename in $(ls $1) | grep -v ".old"
do
mv "$1/$filename" "$1/$filename.old"
done
有修复吗?
答案1
for filename in "$1"/*; do
if [ -f "$filename" ] &&
[ "${filename%.old}" = "$filename" ]
then
mv -- "$filename" "$filename.old"
fi
done
用于grep
文本,并使用 的输出ls
来用眼睛阅读,而不是作为程序的输入。
您收到的错误是由于代码中的语法错误造成的。循环的语法for
(循环多个单词)是
for variable in word-list; do ...; done
顶部的代码将循环遍历给定目录中的所有常规文件$1
,并为它们提供一个.old
文件名后缀(如果它们还没有)。这两个测试测试是否$filename
引用常规文件(或指向该文件的符号链接),以及从其值的末尾$filename
删除时是否保持不变(即它是否已经具有后缀)。.old
做或多或少相同的事情的另一种方法是find
:
find "$1" -maxdepth 1 -type f ! -name '*.old' -exec mv {} {}.old ';'
.old
请注意,如果存在不带后缀的相应文件名,这两种解决方案都会覆盖任何已存在的文件.old
。如果有一个目录带有.old
后缀的$1
文件将被放入该目录中而不是被重命名。
find
该解决方案与 shell 循环之间的区别在于,该find
解决方案还会关心隐藏名称,并且 shell 循环会将符号链接重命名为常规文件。
有关的:
答案2
你基本上已经承认这是一项家庭作业,与现实生活无关。正如评论中所写,您的老师可能希望您这样做
for filename in $(ls "$1" | grep -v '\.old$')
如果你的老师极其愚蠢且无知,他们可能更喜欢你省略引号、the\
和 the $
。请介绍一下你的老师Unix 和 Linux 堆栈交换。但是,如果你的老师不能或不会学习如何正确做事,那就按照他们想要的方式做作业。
然后立即忘记它,因为它有缺陷。
这是一个变体拘萨罗南达的回答 这可能更容易阅读。 (我添加了错误检查,因为那是正确的做法™。)
if [ "$1" = "" ]
then
printf 'Usage: %s <directory-name>\n' "$0"
exit 1
fi
if [ ! -d "$1" ]
then
printf 'Error: %s is not a directory.\n' "$1"
exit 2
fi
for filename in "$1"/*
do
case "$filename" in
(*.old) # Skip
;;
(*)
mv -- "$filename" "$filename.old"
esac
done
您可能还想
$1
处理其中是目录的 情况,但是- 您没有完全权限,或者
- 它是空的。
- 询问是否应该重命名目录、符号链接和其他内容。
答案3
使用 bash 和扩展文件扩展:
shopt -s extglob
for file in !(*.old); do ...