このエラーは引き続き発生します。
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 ...