find 명령의 기본 이름에서 실행

find 명령의 기본 이름에서 실행

다음과 같은 디렉토리 구조가 있다고 가정합니다.

test
test/a
test/b

이제 .폴더에서 파일 ab.

그래서 기본적으로 나는 이런 것을 원했고 순진하게 시도했습니다.

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

단지 이로 인해 빈 파일 ab상위 디렉터리가 생성되지는 않습니다. 내 터치 명령이 하나의 매개변수만 취할 수 있다고 가정해 보겠습니다.

그러면 다음과 같은 디렉토리 구조가 생성됩니다.

a
b
test
test/a
test/b

나는 bash 스크립트에서 이 작업을 수행하는 방법을 알고 있지만 단일 명령 솔루션에 관심이 있습니다.

답변1

배시를 실행합니다.

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

이것이 ${1##*/}의미하는 바는 a 로 끝나는 두 번째 매개변수에서 가장 긴 일치 항목을 제거하여 /마지막 매개변수 이후의 모든 항목을 유지한다는 것 입니다 /.

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}문자열 조작 구성을 사용하여 접두사 일치를 제거할 수 있습니다 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)

관련 정보