意外标记 ` | 附近出现语法错误'

意外标记 ` | 附近出现语法错误'

我不断收到此错误

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 ...

相关内容