이 xargs 명령이 작동하지 않는 이유는 무엇입니까? mv {} `basename {} .sh` 그러나

모든 .sh 확장자를 삭제하고 싶었습니다.

ls *.sh | xargs -I {} mv {} `basename {} .sh`

그러나 작동하지 않으면 basename변경되지 않은 파일 이름을 반환 하는 것처럼 작동 합니다.

왜 그런 식으로 작동합니까?

예를 들어 다음과 같이 작동합니다.

ls *.sh | xargs -I {} echo `basename {}.jpg .jpg`;

편집 :

솔루션 : 작은 따옴표 `basename ...`는 명령이 실행되기 전에 쉘이 평가 하지 못하게 합니다.

ls *.sh | xargs -I {}  sh -c 'mv {} `basename {} .sh`'


답변

파이프 라인이 실행되기 전에 basename 명령이 실행되기 때문입니다. 이 작업을 수행하려면 기본 이름을 실행하기 위해 xargs가 필요합니다 sh -c. 예를 들면 다음 과 같습니다.

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

노트:

  • xargs파일 이름을 삽입 할 위치를 알려주지 않으면 명령 줄 끝에 추가됩니다.
  • -L1스위치 나 이에 상응하는 기능을 사용해야 하므로 xargs인수 하나만 전달합니다 sh.
  • 출력을 사용하면 원하지 않는 효과ls 가있을 수 있습니다 .

편집하다

TechZilla 덕분에 더 이상 사용되지 않는 옵션 제거


답변

귀하의 질문에 대해 잘 모르겠습니다. 실제로 첫 번째 줄이 왜 작동하지 않는지 묻고 있습니까? 아니면 모든 .sh 파일의 이름을 바꾸는 적절한 방법을 찾고 있습니까?

가장 깨끗한 방법이라고 가정하기 전에 전에 명령 옵션을 준비하는 것을 선호합니다 xargs. .sh 파일 확장자를 제거하기 위해 종종이 접근법을 고려합니다.

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv