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
이것이 당신이 원하는 것입니다. 화타이
답변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
에코를 제거하고 기능이 실제로 작동하도록 만드세요.