ls出力用のForeachループ

ls出力用のForeachループ

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移植性が必要な場合はそうではありません。

おすすめ記事