find コマンドのデフォルト名から実行

find コマンドのデフォルト名から実行

次のディレクトリ構造があるとします。

test
test/a
test/b

.フォルダ内のファイルab

だから基本的に私はこのようなことを望み、素朴に試しました。

find test -type f -exec touch `basename {}` \;

ただ、これは空のファイルab親ディレクトリを生成しません。私のタッチコマンドが1つのパラメータしか取れないとしましょう。

これにより、次のディレクトリ構造が作成されます。

a
b
test
test/a
test/b

私はbashスクリプトでこれを行う方法を知っていますが、単一のコマンドソリューションに興味があります。

答え1

バッシュを実行します。

find ... -exec bash -c 'touch "${1##*/}"' btouch {} \;

これ${1##*/}が意味するのは、aで終わる2番目のパラメータから最も長い一致を削除して、/最後のパラメータ以降のすべての項目を保持することです/

btouchアクティブなプロセスのリストに正しく表示されるように仮想名を使用できます(ps)。

答え2

自分でリスクを取って試してみてください。

find test -type f -exec echo touch \"\$\(basename "'{}'"\)\" \; | bash

スペースを含むファイル名を使用してテストします。

答え3

execdir次のオプションを試してくださいfind。デフォルト名のみを引数として使用して、ファイルディレクトリに指定したコマンドを実行します。

私が知っている限り、「main」ディレクトリに「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

答え4

パスでいくつかの文字列処理を実行するには、シェルを呼び出します。${VARIABLE##PATTERN}文字列操作構成を使用して、プレフィックス一致を削除できますPATTERNVARIABLEパターン*/は先行ディレクトリ名を削除します。

find test -type f -exec sh -c 'for x; do touch "${x##*/}"; done' _ {} +

GNU findを使用するもう1つの方法は、それをサブディレクトリに変更することです。シェルを呼び出して元のディレクトリに戻ります。

find test -type f -execdir sh -c 'cd "$0" && touch -- "$@"' "$PWD" {} +

または、あきらめてfindzshを使用してください。具体的には以下を追加してください。t 履歴修飾子としてグローバル予選

touch test/**/*(:t)

関連情報