次のようなディレクトリ構造があるとします。
test
test/a
test/b
ここで、.
フォルダーで、ファイルa
およびb
のベース名でコマンドを実行できるようにコマンドを実行します。
だから基本的にはこういうものが欲しいので素朴にやってみました
find test -type f -exec touch `basename {}` \;
ただ、これによって親ディレクトリに空のファイルa
とb
が作成されることはありません。私のtouchコマンドが取ることができる引数は1つだけだとします。
これにより、次のようなディレクトリ構造になります。
a
b
test
test/a
test/b
私はbashスクリプトでこれを行う方法を知っていますが、単一のコマンドソリューションに興味があります。
execdir
のfind
オプションを試してください。引数としてベース名のみを使用して、ファイルのディレクトリで指定したコマンドを実行します。
私が集めたものから、あなたは「メイン」ディレクトリに「a」と「b」を作成したいと思います。これは、$PWD
オプションと-execdir
オプションを組み合わせることで実現できます。以下の解決策をご覧ください。 (&& find … ls
の部分は出力専用なので、効果を確認できます。&&
の前にコマンドを使用することをお勧めします。)
まず、テスト環境を設定します。
-----[ 15:40:17 ] (!6293) [ :-) ] janmoesen@mail ~/stack
$ mkdir test && touch test/{a,b} && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
これは、単純な-exec
を使用した場合に発生します—元のファイルが変更されます。
-----[ 15:40:30 ] (!6294) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -exec touch {} \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
ただし、$PWD
を引数プレースホルダー{}
と組み合わせて-execdir
を使用すると、(私が思うに)必要なものが得られます。
-----[ 15:40:57 ] (!6295) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -execdir touch "$PWD/{}" \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:41 ./
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./b
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
Bashを実行します。
find ... -exec bash -c 'touch "${1##*/}"' btouch {} \;
ここで、${1##*/}
は、/
で終わる2番目の引数から最長の一致を削除し、最後の/
以降のすべてを保持することを意味します。
btouch
は、アクティブなプロセスリストに正しく表示されるように、任意のダミー名にすることができます(ps
)
ご自身の責任でこれを試してください:
find test -type f -exec echo touch \"\$\(basename "'{}'"\)\" \; | bash
スペースを含むファイル名でテストされています。
シェルを呼び出して、パスで文字列処理を少し実行します。 ${VARIABLE##PATTERN}
文字列操作構造を使用して、PATTERN
からVARIABLE
に一致するプレフィックスを削除できます—パターン*/
は先頭のディレクトリ名を削除します。
find test -type f -exec sh -c 'for x; do touch "${x##*/}"; done' _ {} +
GNU findを使用する別の方法は、サブディレクトリに変更することです。シェルを呼び出して、元のディレクトリに戻します。
find test -type f -execdir sh -c 'cd "$0" && touch -- "$@"' "$PWD" {} +
または、find
を削除してzshを使用します。具体的には、t
履歴修飾子 を グロブ修飾子 として追加します。
touch test/**/*(:t)
これはどう?
$ touch $(find test -type f -exec basename {} \;)