foreachループを使用してディレクトリ内のいくつかのファイルを処理してls出力を取得しようとしています。
IFS=$'\n'
for i in $(ls -1Atu); do
echo "$i"
done
最初はうまくいくと思いましたが、*
orと同じ名前のファイルを作成したときにfilename*
シェルが*
ワイルドカードとして解釈されたため、追加の繰り返しを追加しました。
ただし、このようにls出力をエスケープするとfor i in "$(ls -1Atu)";
繰り返しが発生し、$ iはlsの出力を完全に含みます。
この問題をどのように解決できますか?より良いバリエーションを含むls -1Atu
結果ファイルは、必要に応じて時間ごとにソートされます。ありがとう
ベストアンサー1
背景素材:スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?、lsの出力を解析しない理由
改行に設定すると、IFS
コマンド置換拡張中にスペースやタブではなく改行のみが区切り文字と見なされます。あなたの方法は改行文字を含むファイル名をサポートしません。これは1の基本的な制限ですls
。
また、これが問題です。この設定は、IFS
コマンドが拡張機能をオーバーライドしたときに発生する他の作業(ワイルドカードの一致など)には影響しません。ワイルドカードをオフにすると、ファイル名に改行文字が含まれていない限り、スクリプトは機能します。
IFS='
'
set -- *"$IFS"*
if [ -e "$1" ]; then
echo >&2 "There are file names with newlines. I cannot cope with this."
exit 2
fi
set -f
for i in $(ls -1Atu); do
printf '%s\n' "$i"
done
set +f
unset IFS
日付別にファイルをリストする簡単で信頼性の高い方法は、zshなどの純粋なBourneスタイルのシェル以外のものを使用することです。グローバル予選ワイルドカードの一致がソートされる方法を変更します。
#!/bin/zsh
files_by_access_time=(*(Doa))
1一部の実装ではこの問題を解決できますが、ls
移植性が必要な場合はそうではありません。