다음 명령이 있습니다.
ls /some/path/*dat | xargs -n 1 -I @ sh -c "echo `basename @`"
디렉토리 /some/path/
에는 다음이 포함됩니다.
/some/path/a
/some/path/b
/some/path/c
/some/path/d
출력을 얻고 싶습니다.
a
b
c
d
그러나 나는 여전히 전체 경로를 얻습니다. 내가 뭘 잘못했나요?
basname
편집: 그런데, 대신 실행할 수 있는 더 쉬운 방법이 있다는 것을 알고 있습니다.
echo `basename @`
하지만 다음과 같은 복잡한 명령을 실행해야 합니다.
octave --silent --eval "somefunction('`basename @`','@',...))"
편집 2:
실제 명령은 다음과 같습니다.
ls ~/phd/data/conll2012/dev.megam/*dat | xargs -P 16 -n 1 -I@ timeout -k 1s 15m sh -c "if [ ! -f '~/phd/xp/conll2012/dev.megam/@.$epsilon$mink$minn$alpha' ]; then octave --silent --eval \"xprp('~/phd/xp/conll2012/dev.megam/@.$epsilon$mink$minn$alpha.rp','@',$alpha,$mink,$minn,$epsilon);\" 2>> ~/xpgrid.log;fi"
기본적으로 디렉터리에 파일 세트가 있고 이 명령은 해당 파일을 가져와 결과를 다른 디렉터리에 출력하여 결과가 존재하지 않는지 확인합니다.
따라서 전체 경로가 포함된 파일과 기본 이름만 포함된 파일이 필요합니다.
어떻게 작동하게 만들까요? 처음에 간단한 예를 보면 이를 더 명확하게 이해하는 데 도움이 될 수 있습니다.
답변1
ls /some/path/*dat | xargs -n 1 -I @ sh -c 'echo `basename "@"`'
코드에서 너무 일찍 실행되었습니다 basename
.
경로에 공백이나 탭이 없는지 확실하지 않은 경우 ( -d \\n
또는 find ... -print0 | xargs -0 ...
)를 사용하고 주의해야 합니다."
@
답변2
큰따옴표를 작은따옴표로 변경하면 테스트 사례가 수정되지만 GNU에 대해 알고 싶을 수도 있습니다 parallel
.
다음과 같이 동일한 작업을 수행할 수 있습니다.
parallel echo {/} ::: /some/path/*dat
(일부 쉘에서는 중괄호를 인용해야 할 수도 있습니다.)
더 깔끔한 구문 외에도 parallel
여러 명령이 동시에 실행됩니다.
두 번째 예는 다음과 같습니다.
parallel octave --silent --eval "\"somefunction('{/}', '{}', ...)\"" ::: /some/path/*dat
(인용문은 2번 평가되기 때문에 반드시 인용문 안에 들어가야 합니다.)
답변3
# find all my perl file names with *.pl or *.pm ext sorted
find src/ -name '*.pm' -o -name '*.pl' \
| xargs -n 1 -I @ sh -c 'echo `basename "@"`' | sort