それは私を夢中にさせています。次の bash スクリプトを用意します。
testdir="./test.$$"
echo "Creating a testing directory: $testdir"
mkdir "$testdir"
cd "$testdir" || exit 1
echo "Creating a file word.txt with content á.txt"
echo 'á.txt' > word.txt
fname=$(cat word.txt)
echo "The word.txt contains:$fname"
echo "creating a file $fname with a touch"
touch $fname
ls -l
echo "command: bash cycle"
while read -r line
do
[[ -e "$line" ]] && echo "$line is a file"
done < word.txt
echo "command: find . -name $fname -print"
find . -name $fname -print
echo "command: find . -type f -print | grep $fname"
find . -type f -print | grep "$fname"
echo "command: find . -type f -print | fgrep -f word.txt"
find . -type f -print | fgrep -f word.txt
Freebsd では (おそらく Linux でも)、次の結果が得られます。
Creating a testing directory: ./test.64511
Creating a file word.txt with content á.txt
The word.txt contains:á.txt
creating a file á.txt with a touch
total 1
-rw-r--r-- 1 clt clt 7 3 júl 12:51 word.txt
-rw-r--r-- 1 clt clt 0 3 júl 12:51 á.txt
command: bash cycle
á.txt is a file
command: find . -name á.txt -print
./á.txt
command: find . -type f -print | grep á.txt
./á.txt
command: find . -type f -print | fgrep -f word.txt
./á.txt
Windows 7 (cygwin がインストールされている) でも、スクリプトを実行すると正しい結果が得られます。
しかし、OS X bash でこのスクリプトを実行すると、次のようになりました。
Creating a testing directory: ./test.32534
Creating a file word.txt with content á.txt
The word.txt contains:á.txt
creating a file á.txt with a touch
total 8
-rw-r--r-- 1 clt staff 0 3 júl 13:01 á.txt
-rw-r--r-- 1 clt staff 7 3 júl 13:01 word.txt
command: bash cycle
á.txt is a file
command: find . -name á.txt -print
command: find . -type f -print | grep á.txt
command: find . -type f -print | fgrep -f word.txt
そのためbash
、ファイルが見つかりá.txt
ませfind
んでしgrep
た。:(
最初にapple.stackexchangeで質問され、ファイル名の変換に使用することを提案する1つの回答。iconv
$ find . -name $(iconv -f utf-8 -t utf-8-mac <<< á.txt)
これは「OS X」では機能しますが、とにかくひどいです。(端末に入力するutf8文字列ごとに別のコマンドを入力する必要があります。)
一般的なクロスプラットフォームの bash プログラミング ソリューションを見つけようとしています。したがって、質問は次のとおりです。
- OS X で
bash
ファイルが「見つかった」のに見つからないのfind
はなぜですか?
と
- Unicode ファイル名がファイルに保存されるクロスプラットフォームの bash スクリプトを作成する方法。
- 唯一の解決策は、? を使用して OS X 専用の特別なバージョンを作成することです。
iconv
- などの他のスクリプト言語用の移植可能なソリューションは
perl
ありますか?
Ps: そして最後に、実際にはプログラミングに関する質問ではありませんが、分解されたファイル名を使用してコマンド ラインでうまく動作しない Apple の決定の背後にある理論的根拠は何なのか疑問に思っています。utf8
編集
シンプルod
。
$ ls | od -bc
0000000 141 314 201 056 164 170 164 012 167 157 162 144 056 164 170 164
a ́ ** . t x t \n w o r d . t x t
0000020 012
\n
と
$ od -bc word.txt
0000000 303 241 056 164 170 164 012
á ** . t x t \n
0000007
だから
$ while read -r line; do echo "$line" | od -bc; done < word.txt
0000000 303 241 056 164 170 164 012
á ** . t x t \n
0000007
検索からの出力は次と同じですls
$ find . -print | od -bc
0000000 056 012 056 057 167 157 162 144 056 164 170 164 012 056 057 141
. \n . / w o r d . t x t \n . / a
0000020 314 201 056 164 170 164 012
́ ** . t x t \n
そのため、word.txt
そのコンテンツから作成されるファイルは IS DIFFERENT とは異なります。bash
したがって、ファイルが見つかった理由はまだ説明されていません。