ls | grep pattern -
와 일치 할 때마다 Java 명령을 한 번 실행하고 싶습니다.이 경우 find pattern -exec Java MyProg '{}' \;
를 수행 할 수 있다고 생각하지만 일반적인 경우- "모든 표준 입력 라인에 대해 명령을 한 번 실행"하는 쉬운 방법이 있습니까? (물고기 또는 배쉬)
그것이 xargs
의 역할입니다.
... | xargs command
허용 된 답변 옳은 생각이 있지만, 열쇠는 xargs
the -n1
스위치 : "출력 라인 당 한 번 명령 실행 :"
cat file... | xargs -n1 command
또는 단일 입력 파일의 경우 cat
에서 파이프를 완전히 피하고 다음을 수행 할 수 있습니다.
<file xargs -n1 command
Bash 또는 다른 Bourne 스타일 쉘 (ash, ksh, zsh 등) :
while read -r line; do command "$line"; done
read -r
는 표준 입력 (read
없이 -r
는 백 슬래시를 해석하므로 원하지 않습니다). 따라서 다음 중 하나를 수행 할 수 있습니다.
$ command | while read -r line; do command "$line"; done
$ while read -r line; do command "$line"; done <file
Keith에게 동의합니다. xargs는 작업을위한 가장 일반적인 도구입니다.
나는 보통 3 단계 접근법을 사용합니다.
더 작고 빠른 방법이 있지만이 방법은 거의 항상 작동합니다.
간단한 예 :
ls |
grep xls |
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' |
xargs -0 bash -c
첫 번째 두 줄은 작업 할 파일을 선택한 다음 awk는 실행할 명령과 일부 인수를 사용하여 Nice 문자열을 준비하고 $ 1은 파이프의 첫 번째 열 입력입니다. 마지막으로 xargs 가이 문자열을 bash로 보내어 실행시킵니다.
약간 과잉이지만이 레시피는 매우 유연하기 때문에 많은 곳에서 도움이되었습니다.
이런 종류의 작업을 위해 GNU Parallel이 만들어졌습니다. 가장 간단한 사용법은 다음과 같습니다.
cat stuff | grep pattern | parallel Java MyProg
자세한 내용은 소개 동영상을 참조하십시오. http://www.youtube.com/watch?v=OpaiGYxkSuQ
또한 생선 껍질의 while read
루프 ( fish 태그를 사용한 것을 고려하면 생선 껍질을 원한다고 가정합니다).
command | while read line
command $line
end
몇 가지 유의할 사항.
read
는 -r
인수를 사용하지 않으며 가장 일반적인 사용 사례를 쉽게 만들기 위해 백 슬래시를 해석하지 않습니다.$line
를 인용 할 필요는 없습니다.command
자체는 구문 오류 (자리 표시 자 인수의 이러한 사용을 잡기 위해)입니다. 실제 명령으로 바꾸십시오.잠재적으로 위생 처리되지 않은 입력을 처리 할 때, 전체 작업을 실행하기 전에 (특히 사람들의 우편함 청소와 같은 파괴적인 경우) 육안 검사를 위해 한 줄씩 '맞춤법'을보고 싶습니다.
그래서 내가하는 일은 매개 변수 목록 (예 : 사용자 이름)을 생성하고 다음과 같이 한 줄에 하나씩 레코드로 파일에 공급하는 것입니다.
johndoe
jamessmith
janebrown
그런 다음 vim
에서 목록을 열고 다음과 같이 실행해야하는 전체 명령 목록을 얻을 때까지 검색 및 바꾸기 식으로 맹 글링합니다.
/bin/rm -fr /home/johndoe
/bin/rm -fr /home/jamessmith
이런 식으로 정규 표현식이 불완전한 경우 어떤 명령에서 잠재적 인 문제가 발생하는지 확인할 수 있습니다 (예 : /bin/rm -fr johnnyo connor
). 이렇게하면 정규식을 취소하고보다 안정적인 버전으로 다시 시도 할 수 있습니다. 이름 맹 글링은 Van Gogh, O'Connors, St. Clair, Smith-Wesson과 같은 모든 Edge 사례를 처리하기가 어렵 기 때문에 악명 높은 것으로 유명합니다.
set hlsearch
은 (는) vim
에서이 작업을 수행하는 데 유용합니다. 모든 일치 항목을 강조 표시하므로 일치하지 않는 경우 또는 의도하지 않은 방식으로 일치하는 항목을 쉽게 찾을 수 있습니다.
정규 표현식이 완벽하고 테스트/생각할 수있는 모든 사례를 포착하면 일반적으로 sed 표현식으로 변환하여 다른 실행을 위해 완전히 자동화 할 수 있습니다.
입력 행 수로 인해 육안 검사를 수행 할 수없는 경우에는 명령을 실행하기 전에 화면 (또는 더 나은 로그)에 명령을 에코하는 것이 좋습니다. 따라서 오류가 발생하면 어떤 명령이 발생했는지 정확하게 알고 있습니다 실패합니다. 그런 다음 원래 정규식으로 돌아가서 한 번 더 조정할 수 있습니다.
여기에서 즉시 사용할 수있는 카피 페이스트 :
cat list.txt | xargs -I{} command parameter {} parameter
목록의 항목은 {} 위치에 배치되고 나머지 명령 및 매개 변수는 그대로 사용됩니다.
다른 답변과 같이 xargs
로 가능합니다. 질문의 "한 줄에 한 번"부분에서 두 가지 특성을 구별해야합니다.
-n 1
를 사용하면 각 인수에 대해 명령이 정확히 한 번만 호출됩니다. 그러나 기본적으로 xargs
는 인수가 공백으로 구분되어 있다고 가정합니다. 파일에 공백이 있으면 중단됩니다.-d '\n'
를 사용하거나 tr '\n' '\0'
로 입력을 사전 처리하고 -0
를 사용하십시오. 이것은 입력의 공백에 대해 명령을 강력하게 만듭니다.최종 명령 행은 다음과 같습니다.
.... | xargs -n 1 -d '\n' <command>
또는 (tr
사용)
.... | tr '\n' '\0' | xargs -n 1 -0 <command>
명령이 여러 인수를 한 번에 처리 할 수있는 경우 (예 : grep
또는 sed
) -n 1
를 생략하여 작업 속도를 높일 수있는 경우가 많습니다.
프로그램이 파이프를 무시하지만 파일을 인수로 허용하는 경우 특수 파일 /dev/stdin
를 가리킬 수 있습니다.
Java에 익숙하지 않지만 다음은 bash에서 어떻게 수행하는지에 대한 예입니다.
$ echo $'pwd \n cd / \n pwd' |bash /dev/stdin
/home/rolf
/
Bash가 \n
를 개행으로 변환하려면 $가 필요합니다. 왜 그런지 잘 모르겠습니다.
나는 이것을 선호한다-여러 줄 명령과 명확한 코드 허용
find -type f -name filenam-pattern* | while read -r F
do
echo $F
cat $F | grep 'some text'
done