이 xargs 명령이 작동하지 않는 이유는 무엇입니까?

이 xargs 명령이 작동하지 않는 이유는 무엇입니까?

모든 .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`'

답변1

파이프라인이 실행되기 전에 basename 명령이 실행되기 때문입니다. 이 작업을 수행하려면 basename에 대한 xargs가 필요합니다. sh -c예를 들어 다음을 사용하여 이 작업을 수행할 수 있습니다.

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

노트:

  • 파일 이름을 어디에 삽입해야 할지 모르면 xargs명령줄 끝에 추가됩니다.
  • -L1스위치나 이에 상응하는 스위치를 사용해야 하므로 xargs하나의 인수만 에 전달하세요 sh.
  • 사용되는 출력은 ls다음과 같습니다.부작용.

편집하다

TechZilla 덕분에 더 이상 사용되지 않는 옵션이 제거되었습니다.

답변2

귀하의 질문에 대해 잘 모르겠습니다. 첫 번째 줄이 작동하지 않는 이유를 정말로 묻는 것입니까? 아니면 모든 .sh 파일의 이름을 바꾸는 올바른 방법을 찾고 계십니까?

이것이 가장 깔끔한 방법이라고 가정하면 xargs. .sh 파일 확장자를 제거하기 위해 저는 종종 이 방법을 고려하는데,

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

관련 정보