STDIN에서 가져온 각 줄에 대해 쉘 명령을 실행하고 싶습니다.
이 경우에는 xargs mv
. 예를 들어, 다음 두 줄이 주어집니다.
mfoo foo
mbar bar
나는 다음을 실행하고 싶습니다 :
xargs mv mfoo foo
xargs mv mbar bar
ruby
나는 , awk
및 를 사용하여 다음 전략을 시도했습니다 xargs
. 그러나 나는 잘못하고 있습니다.
단지 xargs
:
$ echo "mbar bar\nmbaz baz" | xargs mv
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
을 통해 awk
:
$ echo "mbar bar\nmbaz baz" | awk '{ system("xargs $0") }'
을 통해 ruby
:
$ echo "mbar bar\nmbaz baz" | ruby -ne '`xargs mv`'
$ ls
cat foo mbar mbaz
질문이 몇 개 있습니다:
- 내가 하려는 일을 어떻게 해야 하나요?
- 내 시도마다 어떤 문제가 있습니까?
- 내가 하려는 일에 대해 "생각"하는 더 좋은 방법이 있습니까?
xargs
특히 다음이 작동하기 때문에 내 시도가 작동하지 않는다는 사실이 혼란스럽습니다 .
$ echo "foo\nbar" | xargs touch
$ ls
bar foo
답변1
echo "mbar bar\nmbaz baz" | xargs mv
무슨 일이 일어나고 있는지 확인하려면 옵션 xargs
을 사용해야합니다 . 따라서 위의 경우 에서 를 -t
호출하면 다음과 같은 내용이 표시됩니다.xargs
-t
mv mbar bar mbaz baz
그러니 당연히 옳지 않습니다. 배고픈 악어 처럼 xargs
파이프를 통해 공급되는 모든 인수를 먹었습니다 echo
. 따라서 croc에 대한 인수 릴리스를 제한하는 방법이 필요합니다. 그리고 라인별로 요청했으므로 필요한 것은 -l
또는 -L
for POSIX 옵션입니다.
echo "mbar bar\nmbaz baz" | xargs -l -t mv
POSIX 방식:
echo "mbar bar\nmbaz baz" | xargs -L 1 -t mv
mv mbar bar
mv mbaz baz
그리고 이것이 당신이 원했던 것입니다. HTH
답변2
이 방법으로 갈 수 있습니다 :
echo -e "foo bar\ndoo dar" | xargs -n 2 mv
파일에서 읽으려면:
cat lines.txt | xargs -n 2 mv
또는
xargs -a lines.txt -n 2 mv
답변3
xargs
예상대로 동작하지 않을 수도 있습니다. 이 질문에 대한 @MichaelHomer의 의견을 참조하십시오.
xargs mv mfoo foo
입력을 기다리고 입력되는mfoo foo $x_1 $x_2 $x_3...
모든 줄에 대해 mv를 실행합니다.$x_n
@마이클호머
이는 본문을 읽어보면 확인할 수 있습니다.xargs
매뉴얼 페이지:
설명
xargs 유틸리티는 표준 입력에서 공백, 탭, 개행 및 파일 끝으로 구분된 문자열을 읽고 해당 문자열을 인수로 사용하여 유틸리티를 실행합니다.
실제로는 xargs
첫 번째 인수로 지정된 명령줄 유틸리티에 인수를 공급할 때 줄바꿈을 무시하는 것처럼 보입니다. 예를 들어 개행 문자에 어떤 일이 발생하는지 확인하세요.
$ echo "foo bar\ncat dog"
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs echo
foo bar cat dog
이 동작은 다음을 사용하여 제어할 수 있습니다.-n
깃발:
-n 숫자
각 유틸리티 호출 에 대해 표준 입력에서 가져온 최대 인수 수를 설정합니다 .
이전 예제로 돌아가서 xargs
2개의 인수만 취하고 종료하면 다음을 사용할 수 있습니다.@ddnomad의 접근 방식:
$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog
또한 Rakesh Sharma의 답변에 있는 주석에서 볼 수 있듯이 BSD에서는 xargs
플래그를 사용하여 읽을 줄 수를 지정할 수 있습니다 -L
. 매뉴얼 페이지에서:
-L 번호
읽은 모든 숫자 행에 대해 유틸리티를 호출합니다. EOF에 도달하고
숫자보다 적은 행을 읽은 경우 사용 가능한 행으로 유틸리티가 호출됩니다.
테스트에도 마찬가지로 유용한 스위치는 -t
다음과 같습니다.
예제를 다시 살펴보면 다음 두 가지가 모두 작동합니다. 그러나 두 번째 예는 이 경우 의도한 것이기 때문에 더 좋습니다.
$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs -L 1 echo
foo bar
cat dog
매뉴얼 페이지의 참고 사항:
-L 및 -n 옵션은 상호 배타적입니다. 마지막으로 주어진 것이 사용됩니다.
답변4
xargs를 사용하지 않는 매우 간단한 솔루션이 있습니다.
이 함수를 정의하십시오:
$ mv2() { while (($# >1 )); do echo mv "$1" "$2"; shift 2; done; }
그런 다음 필요한 파일 이름 목록을 사용하여 호출하세요(줄 바꿈 필요 없음).
$ mv2 mbar bar mbaz baz
mv mbar bar
mv mbaz baz
기능이 실제로 작동하도록 하려면 에코를 제거하십시오.