トークン ` |

トークン ` |

このエラーは引き続き発生します。

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これら2つのテストは、$filename通常のファイルが参照されているか(またはそれを指すシンボリックリンク)、$filename値の末尾から削除されたときに変更されていない(つまり、すでにサフィックスがあるかどうか)テストします。.old

ほぼ同じことを行うもう1つの方法は次のとおりですfind

find "$1" -maxdepth 1 -type f ! -name '*.old' -exec mv {} {}.old ';'

.oldサフィックスのない対応するファイル名がある場合、両方のソリューションは既存のファイルを上書きします.old。もしあれば目次.oldサフィックスが付いたファイルは、$1名前が変更されずにこのディレクトリに配置されます。

findこのソリューションとシェルループの違いは、このfindソリューションは隠された名前にも興味があり、シェルループはシンボリックリンクの名前を一般ファイルに変更することです。

関連:

答え2

あなたは基本的にこれが宿題であり、実際の生活とは関係がないことを認めました。コメントに書かれているように、先生がこうするように言うこともできます。

for filename in $(ls "$1" | grep -v '\.old$')

先生が非常に愚かで無知な場合は、引用符、\およびを省略することをお勧めします$。先生紹介お願いします。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

バッシュを使って拡張ファイル拡張子:

shopt -s extglob
for file in !(*.old); do ...

関連情報