優れた投稿 here を使用して簡単なタスクを実行しようとしています。フォルダに含まれている.txtファイルにリストされているファイル以外のすべてのファイルをフォルダから削除したいと思います。構文は正常に機能しますが、何らかの理由ですべてのファイルが削除されます-基本的に、スクリプトは、フォルダー内のファイル名と.txtファイル内のファイル名の間に対応がないと述べていますが、存在することがわかります!
ファイル名の後に(フォルダーまたは.txtファイルで)見えない空白が表示されているのではないかと思いました。しかし、私はそうは思いません...私が考えていない別の解決策はありますか?
a.txt
ファイルには、Windowsなどの他のOSで作成または編集された可能性があるため、隠し文字が含まれているようです。
構文エラーなしで使用するには、まずファイルをサニタイズする必要があります。
最も簡単な方法は、dos2unixというツールを使用することです。以下の手順に従ってください:
最初:ターミナルを開いて次のコマンドを実行し、dos2unix
をインストールします。
Sudo apt install dos2unix
2番目:a.txt
ファイルをバックアップします。
番目に:dos2unix
ファイルを含むディレクトリ内からターミナルで次のコマンドを実行して、ファイルでa.txt
を使用します。
dos2unix a.txt
最後に:ファイルをテストします。今は大丈夫だろう。
あなたが参照している script は誤検知を引き起こします。 for
は、ファイル名を文字どおりに展開します。これは、特殊文字が保持され、パターンとしてそれを使用すると一致が壊れることを意味します。
例:
#!/bin/bash
# the script is adapted and slightly shortened.
shopt -s nullglob
for i in a* b*; do
grep -Fx -e "$i" exclude.txt
done
出力:
$ ls
a 'a'$'\n''b' b exclude.txt
$ cat exclude.txt
a
b
$ script.sh
a
a
b
b
より良いアプローチは、シェルエスケープを保持することです。
#!/bin/bash
shopt -s extglob
eval "list=( \
$(ls --quoting-style=Shell-escape !(exclude.txt) | \
grep -vFx -f exclude.txt))"
for i in "${list[@]}"; do ls "$i"; done
例:
$ cat exclude.txt
'a'$'\n''b'
$ script.sh
a
b
$ cat exclude.txt
a
b
$ script.sh
'a'$'\n''b'