すべてのディレクトリとサブディレクトリの機能を印刷する

すべてのディレクトリとサブディレクトリの機能を印刷する

以下の関数を使用してすべてのサブディレクトリを印刷しようとしていますが、何らかの理由でファイル名にスペース( "")が含まれている場合、名前はecho2つの部分に分割されます。例は次のとおりです。

私のディレクトリにはというディレクトリが含まれていますr1 August.request

出力は次のとおりです

r1

August.request

私が探しています

r1     August.request

これは私のスクリプトです。

#!/bin/bash

function ScanFile {
    for file in `ls` ; do  
    if [[ -d "$file" ]] ; then
            cd "$file"
            ScanFile
            cd ..
            else
            echo "$file"
    fi
    done
} 
ScanFile

答え1

SH互換シェルにはいわゆるIFS変数があります。 IFS代表内部フィールド区切り記号。この変数は、シェルがパラメータ境界(位置パラメータの境界など)を検出する方法を制御します。

基本的には次のようになります。

set IFS=$' \t\n'

これは、入力をスペース、タブ、および改行区切りトークンに分割することを意味します。

ファイルはスペースで構成されています。この試み:

OLD_IF="$IFS"
IFS=$'\t\n'
for file in `ls -1` ; do
     # Content of your loop
done
IFS="$OLD_IFS"

ここで重要なのは、以前のIFS値を保存して復元することです。

編集:ls -11行に1つのファイルのリストを追加して、上記の操作を実行します。

答え2

バッシュから:

shopt -s globstar
ls -1d **/

答え3

関数解析の引用符なしの出力ですls。これはシェルですls

代わりに:

dirwalk () {
    indent=${1:-0}

    for name in *; do
        [ ! -e "$name" ] && continue
        if [ -d "$name" ]; then
            printf '%*sDir: "%s"\n' "$indent" "" "$name"
            ( cd "$name" && dirwalk "$(( indent + 4 ))" )
        else
            printf '%*sFile: "%s"\n' "$indent" "" "$name"
        fi
    done
}

またはカラフルなインデントなし

dirwalk () {
    for name in *; do
        [ ! -e "$name" ] && continue
        if [ -d "$name" ]; then
            printf 'Dir: "%s"\n' "$name"
            ( cd "$name" && dirwalk )
        else
            printf 'File: "%s"\n' "$name"
        fi
    done
}

*代わりに出力を使用すると、ファイルls名にスペースが含まれていても、現在のディレクトリを繰り返すために正しく区切られたファイル名のリストが生成されます。

テストは、-e繰り返す項目が実際に存在することを確認することです。空のディレクトリを入力すると、拡張されずに*そのまま残ります*。で一致しないパターンが空になるようにシェルオプションをbash設定できます。nullglobshopt -s nullglob

サブシェル(括弧内)でこれを使用すると、以前のディレクトリに戻ることをcd覚えておく必要はありません。cd ..外部環境は内部環境の影響を受けませ( ... )ん。cd

printf代わりに、echo出力形式をよりよく制御できます。また見てください」なぜprintfがechoより優れているのですか?」。

関連情報