私は指定されたディレクトリのファイルとディレクトリを印刷するプログラムを書いています。ただし、特定の種類のファイルは無視する必要があります。私たちはそれらを.ignorefile
。
だからあなたが望むファイルを得るために検索機能を使用します。ただし、毎回同じエラーが発生しますNo such file or directory
。
また、端末で試してみると、同じパラメータで完全に機能します。
一例:
私の無視ファイルには次のものがあります。
*.txt, *.cpp
.sh
ファイルを実行するときは、「ファイルを無視」と「ディレクトリを無視」という2つのパラメータを入力します。次に、ファイル内のすべてのテキストをスキャンしてパラメータファイルを設定するときに関数を呼び出します
store()
。
ここで私のコードを見ることができます。
function store(){
dir="$1"
find_arg="$2" # Dir ! -name '*.txt' ! -name '*.cpp' -print
echo $find_arg
cmd=`find "$find_arg"`
echo $cmd
}
find_argsを構築する関数は次のとおりです。
function backup()
{
if [ $1="-i" ] && [ -f $2 ]
then
backignore=$2
if [ $3="-d" ] && [ -d $4 ]
then
directory=$4
find_arg=" $directory"
while IFS='' read -r line || [[ -n "$line" ]]; do
find_arg+=" ! -name "
find_arg+="'"
find_arg+=$line
find_arg+="'"
done < "$backignore"
find_arg+=" -print"
store $directory "$find_arg"
else
echo "please entrer a right directory"
fi
else
echo "Please enter a right ignore file"
fi
}
backup $1 $2 $3 $4
私はそれを「sh」ファイルと呼ぶ。
./file.sh -i ignorefile -d Source
出力:
Source ! -name '\*.cpp' ! -name '\*.txt' -print
Source/unix_backup/example_files/backignore
Source/unix_backup/example_files/Documents/rep1/file3.txt
Source/unix_backup/example_files/Documents/rep1/file4.cpp
Source/unix_backup/example_files/Documents/rep3
Source/unix_backup/example_files/Documents/rep3/rep4
Source/unix_backup/example_files/Documents/rep3/rep4/file7.txt
Source/unix_backup/example_files/Documents/rep3/rep4/file8.cpp
答え1
find_arg
単一引数として渡される(二重引用符のため)これは次のことを意味します。find
検索しようとしていますみんなファイルは名前の下にあります。Dir ! -name '*.txt' ! -name '*.cpp' -print
(はい、有効なディレクトリ名です。)printf '%q\n' "$find_arg"
に渡された実際のパラメータを確認してくださいfind
。また、シェルが配列をサポートしている場合は、おそらくパラメータを保存するために使用します。。そしてより多くの引用を使用™!eval
ここでは使用しないでください。find
ファイル名が正しく印刷されます。
答え2
.ignorefileにこのファイルがあると言いましたが、
*.txt, *.cpp
表示された出力ではそうです\*.txt, \*.cpp
。エスケープは*
問題の原因であり、find
アスタリスクをグローバルワイルドカードとして使用するのではなく、文字通りアスタリスクのあるファイルを除外するように指示します。だからしないでください。このバージョンのスクリプトはいくつかのバグを修正し、少し単純化しました。とりわけ、
backup()
関数の基本ロジックからarg処理(およびshの組み込みgetoptsを使用)を分離します。
function store() {
echo find "$@"
find "$@"
}
function backup() {
directory="$1"
backignore="$2"
# skip comments and blank lines
sed -e 's/#.*// ; /^[[:space:]]*$/d' "$backignore" |
while IFS= read -r line ; do
find_arg+=" ! -name '$line'"
done
find_arg+=" -print"
store "$directory" $find_arg
}
usage() {
echo "$(basename $0) [ -d directory ] [ -i ignorefile ]"
exit 1
}
directory=''
backignore='.ignorefile' # default
while getopts "i:d:h" opt ; do
case "$opt" in
d) directory="$OPTARG" ;;
i) backignore="$OPTARG" ;;
*) usage ;;
esac
done
[ -z "$directory" ] && echo "Please provide a directory." && usage
backup "$directory" "$backignore"