0

ファイルのパスの一部がシンボリック リンクでないすべてのファイルを簡単に見つける方法はありますか?

4

3 に答える 3

0

短い:

find myRootDir -type f -print

これは質問に答えるでしょう。

指定されたディレクトリの最後にスラッシュを追加しないように注意してください(ではmyRootDir/なくmyRootDir)。

これは、実際のパスにある実際のファイル以外は印刷されません。symlinkedファイルもsymlinkeddirにファイルもありません。

だが...

指定されたディレクトリにシンボリックリンクが含まれていることを確認したい場合は、その仕事を実行できる小さなbash関数があります。

isPurePath() {
    if [ -d "$1" ];then
        while [ ! -L "$1" ] && [ ${#1} -gt 0 ] ;do
            set -- "${1%/*}"
            if [ "${1%/*}" == "$1" ] ;then
                [ ! -L "$1" ] && return
                set -- ''
              fi
          done
      fi
    false
}

if isPurePath /usr/share/texmf/dvips/xcolor ;then echo yes; else echo no;fi
yes

if isPurePath /usr/share/texmf/doc/pgf ;then echo yes; else echo no;fi
no

したがって、このコマンドを実行すると、ファイルのパスのどの部分もシンボリックリンクではないすべてのファイルを見つけることができます。

isPurePath myRootDir && find myRootDir -type f -print

したがって、何かが印刷された場合、シンボリックリンク部分はありません!

于 2012-12-16T18:15:17.107 に答える
0

簡単な方法はわかりませんが、2つの方法を使用して(実際には本質的に同じです)、質問に完全に答える回答を次に示します。

補助スクリプトの使用

という名前のファイルを作成しますhasnosymlinkinname(または、より適切な名前を選択してください --- 私はいつも名前を選ぶのが苦手でした):

#!/bin/bash

name=$1
if [[ "$1" = /* ]]; then
    name="$(pwd)/$1"
else
    name=$1
fi

IFS=/ read -r -a namearray <<< "$name"

for ((i=0;i<${#namearray[@]}; ++i)); do
   IFS=/ read name <<< "${namearray[*]:0:i+1}"
   [[ -L "$name" ]] && exit 1
done

exit 0

それからchmod +x hasnosymlinkinname。次に、次のように使用しfindます。

find /path/where/stuff/is -exec ./hasnosymlinkinname {} \; -print

スクリプトは次のように機能します。トリックを使用してIFS、ファイル名をパスの各部分 ( で区切られた/) に分解し、各部分を配列に配置しnamearrayます。次に、配列の (累積的な) 部分 (/いくつかの策略のおかげで結合されます) をループし、IFSこの部分がシンボリック リンクである場合 (-Lテストを参照)、成功しないリターン コード ( 1) で終了します。成功の戻りコード ( 0) で終了します。

次にfind、このスクリプトを 内のすべてのファイルに対して実行します/path/where/stuff/is。スクリプトが成功のリターン コードで終了した場合、ファイルの名前が出力されます (ただし、その代わりに、-print他の好きなことを行うことができます)。

ワン (!) ライナー (大画面の場合) を使用して、祖母 (または犬) を感動させる

find /path/where/stuff/is -exec bash -c 'if [[ "$0" = /* ]]; then name=$0; else name="$(pwd)/$0"; fi; IFS=/ read -r -a namearray <<< "$name"; for ((i=0;i<${#namearray[@]}; ++i)); do IFS=/ read name <<< "${namearray[*]:0:i+1}"; [[ -L "$name" ]] && exit 1; done; exit 0' {} \; -print

ノート

この方法は、ファイル名に含まれるスペースや変な記号に関しては 100% 安全です。このコマンドの出力をどのように使用するかはわかりませんが、ファイル名に含まれる可能性のあるスペースや変な記号に関しても安全な適切な方法を使用するようにしてください。-print0または同様のスマートなことを使用しない限り、その出力を別のスクリプトで解析しないでください。

于 2012-12-16T17:35:54.270 に答える
0

このスクリプトを使用できます: (内のコード全体をコピー/貼り付け)

cat<<'EOF'>sympath
#!/bin/bash

cur="$1"
while [[ $cur ]]; do
    cur="${cur%/*}"
    if test -L "$cur"; then
        echo >&2 "$cur is a symbolic link"
        exit 1
    fi
done
EOF

${cur%/*}はbashパラメータ展開です

chmod +x sympath
./sympath /tmp/foo/bar/base
/tmp/foo/bar is a symbolic link
于 2012-12-16T16:31:45.820 に答える