2012-03-07 6 views
11

次のコマンドがあります。 .user.logファイルが存在する場合は、親ディレクトリを印刷する必要があります(hhtwee1)。これはどのように行うことができますか?ファイルを検索し、親ディレクトリのみを表示する

$ cd /nfs//office/ && find . -name '.user.log' 
./hht/info/.user.log 
./wee1/info/.user.log 

答えて

11

ここに何か不足していますか?確かに、この正規表現やルーピングはすべて必要ではなく、1つのライナーがその作業を行います。パス名にスペースがある場合、 "for foo in $()"ソリューションも失敗します。

ただ、親の親を取得するには、xargsのと二回のdirnameを使用して...

# make test case 
mkdir -p /nfs/office/hht/info 
mkdir -p /nfs/office/wee1/info 
touch /nfs/office/hht/info/.user.log 
touch /nfs/office/wee1/info/.user.log 

# parent's parent approach 
cd /nfs//office/ && find . -name '.user.log' | xargs -I{} dirname {} | xargs -I{} dirname {} 

# alternative, have find print parent directory, so dirname only needed once... 
cd /nfs//office/ && find . -name ".user.log" -printf "%h\n" | xargs -I{} dirname {} 

はあなたがfind-printfアクションの書式設定オプションで簡単にこれを行うことができます

./hht 
./wee1 
+0

そして、私は結果のディレクトリfindの許可を見つけることができます。 -name '.user_repo。ログ| xargs -i {} dirname {} | xargs -i {} dirname {} | xargs ll – Rajeev

+0

あなたが参照するのは、 "ls -lA"の一般的な別名です。 xargsはエイリアスではなくコマンドのみを実行します。しかし、代わりに "xargs ls -lA"を実行することができます... – Adam

+0

'xargs'の' -i'フラグはdeprecatedとしてリストされていますので、代わりに '-I'フラグを使用することをお勧めします。 –

3
for file in $(find /nfs/office -name .user.log -print) 
do 
    parent=$(dirname $(dirname $file)) 
    echo $parent 
done 

EDIT:申し訳ありませんが、あなたが祖父母のディレクトリを望んでいることを逃しました。

0
find /nfs/office -name '.user.log' | while read line 
do 
    echo $line | awk -F/ '{print $(NF-1),$NF}' 
done 
0

あなたはこのような何か行うことができます:

cd /nfs/office/ && find . -name '.user.log' | xargs -n1 -I{} expr match {} '\(\.\(\/[^/]*\/\)\?\)' 

xargsは、スラッシュ文字(/dir/)間のディレクトリの最初の試合まで.で始まる部分を抽出するためにexpr matchを使用しています。

次のようになりsedを使用して代替バージョン:

cd /nfs/office/ && find . -name 'file.txt' | sed -r 's|(\./([^/]*/)?).*|\1|' 
1

@trojanfoeは正しい考えを持っています。

while IFS= read -r -d '' -u 9 
do 
    echo "$(dirname -- "$(dirname -- "$REPLY")")" 
done 9< <(find "/nfs/office/" -name '.user.log' -print0) | sort -u 
:あなたはそれだけで ユニークの名前をエコーする場合

while IFS= read -r -d '' -u 9 
do 
    echo "$(dirname -- "$(dirname -- "$REPLY")")" 
done 9< <(find "/nfs/office/" -name '.user.log' -print0) 

thisは、ループ内でそれがどんなファイル名で安全に作業するために取得するだけの方法、およびほとんどすべてのコマンドです

+0

別のファイルディスクリプタを使用している特定の理由はありますか? –

+0

ループ内でstdinを使って何かしたい場合。それは上のリンクで説明されています。 – l0b0

2

(参照を生成しますman find)。 man pageから

cd /nfs//office/ && find . -name '.user.log' -printf "%h\n" 
./hht/info 
./wee1/info 

Screenshot of find manpage

%h\nは、新しいライン上の各ファイルのパスを出力します。

-printfはGNUのみです。これはmacOS(BSDシステム)では動作しません。

0
find -type f -exec bash -c 'echo "${1%/*}"' bash {} \; 
関連する問題