compgen -G
a의 출력을 파이핑했지만 xargs basename
아래와 같이 매개변수를 추가할 때까지 작동하지 못하는 상황이 발생했습니다. xargs -I
다음은 설명 주석과 함께 제가 하려는 작업을 보여주는 스크립트입니다. 두 가지 질문이 있습니다. 해당 질문은 스크립트 뒤에 나타납니다.
# create three files for testing:
touch /tmp/my.file.1.2.txt
touch /tmp/1.my.file.2.txt
touch /tmp/1.2.my.file.txt
# create a glob and verify that it works with compgen:
glob=/tmp/*.file*.txt
compgen -G "$glob"
#output:
/tmp/1.2.my.file.txt
/tmp/1.my.file.2.txt
/tmp/my.file.1.2.txt
# try to get the basename of each file using xargs.
# I thought this would work, but it does not.
compgen -G "$glob" | xargs basename
#output:
basename: extra operand ‘/tmp/my.file.1.2.txt’
Try 'basename --help' for more information.
# eventually I discovered that this would work.
# however, I don't understand why this would work
# but the previous attempt would not, since I
# think that this command is just a more
# explicitly-specified version of the previous
# one.
compgen -G "$glob" | xargs -I{} basename {}
#output:
1.2.my.file.txt
1.my.file.2.txt
my.file.1.2.txt
xargs
다른 명령은 매개변수 없이 사용할 수 있습니다 -I
. 예를 들어, compgen -G "$glob" | xargs ls -al
훌륭하게 작동합니다.
basename
질문 1: 이 스크립트에 필요한 매개변수는 무엇입니까 -I
?
질문 2: 이 결과를 보기 전에는 와 가 서로 동의어라고 생각했는데, 그렇지 않은 것 xargs basename
같습니다 . xargs -I{} basename {}
차이점은 무엇입니까?
이것이 문제가 될지는 의문이지만 만일의 경우에 대비해 이 문제는 bash 5.0.17(1) 릴리스를 실행하는 Ubuntu 20.04.4(5.13.0-35-generic)에서 발생합니다.
이 파일 목록을 생성하는 다른 방법이 있다는 것을 알고 있지만, 앞으로 오류를 방지하기 위해 이해해야 할 기본 사항을 여기서 분명히 이해하지 못하기 때문에 걱정됩니다.
답변1
POSIXbasename
한 번에 하나의 이름만 처리되며 선택적으로 접미사를 제거합니다. 한 번에 최대한 많은 인수를 실행하려고 xargs basename
시도 하지만 실패하여 처리를 위해 각 이름이 한 번 실행됩니다.basename
xargs -I{} basename {}
xargs
basename
출력 비교
printf "foo\nbar\nbaz" | xargs echo basename
그리고
printf "foo\nbar\nbaz" | xargs -I{} echo basename {}
GNU는 basename
접미사를 지정할 필요가 없는 경우 여러 이름을 허용하는 여러 옵션을 지원합니다.
xargs basename -a
이렇게 하면,
xargs basename -s .suffix