각 일치 항목에 대해 Java 명령을 한 번씩 실행하고 싶습니다 ls | grep pattern -
. 이 경우에는 할 수 있을 것 같지만 find pattern -exec java MyProg '{}' \;
일반적인 경우가 궁금합니다. "표준 입력의 각 줄에 대해 한 번씩 명령을 실행"이라고 말하는 쉬운 방법이 있습니까? (물고기나 배쉬에서.)
답변1
수락된 답변아이디어는 옳지만 핵심은 xargs
스위치를 통과하는 -n1
것입니다."명령줄당 최대 1개의 인수를 사용하세요.":
cat file... | xargs -n1 command
또는 단일 입력 파일의 경우 cat
파이핑을 모두 피하고 다음을 사용할 수 있습니다.
<file xargs -n1 command
2020년 8월 5일에 업데이트됨:
나는 또한 사용자 Jander의 의견에 있는 제안에 응답하고 싶습니다. 이 제안은 일부 잘못된 정보가 포함되어 있음에도 불구하고 잘 지지되고 있습니다. 이에 대해서는 지금 설명하겠습니다.
(주장되는) 문제점을 언급하지 않고 -L
옵션을 추천하기 위해 서두르지 마십시오.xargs
후행 공백 함수일으킬 수 있습니다. 제 생각에는 이러한 변화는 득보다 실이 더 많을 것이며 확실히 다음과 같은 경우에 무리가 될 것입니다 -L 1
.한 번에 하나의 비어 있지 않은 라인에서 작동. 공평하게 말하면 매뉴얼 페이지는 xargs
명확 합니다.특징(즉, 문제)는 스위치와 함께 제공됩니다 -L
.
Jander는 의견과 답변을 복음으로 받아들이는 대신 매뉴얼 페이지를 읽는 것처럼 지루한 작업을 수행할 시간이 없었던 서두르고 의심하지 않는 StackOverflow 청중에게 빠른 팁을 요청할 때 이러한 문제를 언급하지 않았으므로 해당 -L
문제를 다루겠습니다. 이제 내 추론은 -L
여행 중에 가져가는 모든 수하물을 자세히 살펴보지 않는 것이 매우 나쁜 조언이라는 것입니다.
에 대한 나의 경멸을 설명하기 위해 -L
누군가(아마 훈련 중에 이 데이터 파일을 만든 고등학교 여름 인턴)가 실수로 입력한 다음 텍스트가 포함된 간단한 입력 파일을 생각해 보겠습니다. 증거는 다음과 같습니다.창 유형파일 이름. 다행히(카르마?) 경영진에 의해 귀하가 새로운 관리인으로 선정되었습니다.
testdata.txt
1
2␠
3
숫자가 포함된 줄에 공백 문자가 있으므로( 브라우저 글꼴에 해당 문자가 시각적으로 표시되지 않는 경우 2
이전 코드에서 SYMBOL FOR SPACE
숫자 뒤에 유니코드 문자 모양으로 표시됨 ) 명령은 다음과 같이 사용합니다.2
xargs -L1
<testdata.txt xargs -L1 echo
..., 다음과 같은(아마도 놀라운) 출력이 생성됩니다.
1
2 3
-L
이는 스위치 지시문 때문입니다.xargs
공백으로 끝나는 줄에 다음 줄을 추가합니다., 이 동작은 후행 공백으로 인해 줄이 제대로 잘리지 않는 이상한 순간의 결과 출력에만 영향을 미칠 수 있습니다. 올바른 입력 파일이 나타날 때까지 기다리는 시한 폭탄 오류입니다.
반면에, 스위치를 사용하는 동일한 명령은 -n 1
더 수용 가능한 출력을 생성합니다.xargs
-L 1
1
2␠
3
그것은 최악이 아닙니다! "무서운" 옵션을 강제로 적용하는 대신 이 -L
스위치를 사용하세요. 이로 인해 실행 중인 환경에 비해 너무 길다고 생각되는 명령줄이 발견되면 프로세스가 종료됩니다.-n
-x
xargs
xargs
스위치의 지시에 따라 후행 공백이 있는 연속된 여러 줄로 구성된 입력 파일과 혼합물에서 "에이전트"라고 하는 화학 시약을 사용하는 -L
경우 이들 모두가 하나로 연결되면 중간 스트림 종료가 발생할 수 있습니다.-x
xargs
슈퍼라인xargs
'라는 정의를 넘어서줄이 너무 깁니다.명령줄의 경우. 상황이 흐려지기 시작하면 다음을 고려하십시오.줄이 너무 깁니다.xargs
실행 중인 플랫폼에 대해 지정된 최대 길이를 기준으로 크기가 결정되며, 겉보기에 의한 추가 오프셋에 의해 결정됩니다.임의의 상수맨 페이지에 더 자세히 설명되어 있습니다. 귀찮은 부정 적분과 미적분학의 원리를 기억하시나요?임의의 상수+ C
부정적분의 해를 적는 것을 잊었기 때문에 퀴즈나 시험에서 점수를 잃었습니까 ? 글쎄, 이것을 -L
당신의 편리한 도구 상자에 추가하면 xargs
, 그 말이 다시 당신의 등을 물게 될 것입니다.
반면에 Value -n
는 이러한 긴 줄을 작은 한입 크기의 한 줄 덩어리로 자르고 공백으로 끝나는지 여부에 관계없이 각 덩어리에 제공된 명령을 한 번에 하나씩 실행합니다. 더 이상 긴 대기열이 없으며, 더 이상 갑자기 종료되어 뒤에서 찌르는 일이 없습니다. Et tu, Brute ?1
xargs
xargs
-x
xargs 매뉴얼 페이지의 문구에 대한 선택적 Segue
왜 표현이 모호하고 불규칙한지 모르겠습니다.공백xargs
다음과 같이 더 잘 정의되고 덜 모호한 옵션 대신 매뉴얼 페이지 전체에서 사용됩니다 .
- 공간이 있는 경우공백하나 이상을 나타냅니다.ASCII 공간수치
- 줄바꿈 이외의 공백(해당되는 경우)공백힌트)
- 그룹에 인쇄할 수 없는 문자가 하나 이상 있습니다.{공백, 가로 탭}(만약에공백이 무서운 듀오의 동의어로 사용됨)
2021년 6월 15일에 업데이트됨:
@BjornW 사용자가 xargs
명령당 한 번씩 명령을 실행하는 방법을 물었습니다.철사단지 입력된 단어가 아닌 입력된 내용입니다. (저는 댓글을 읽었으며 코로나19에 대응하는 데 7개월이 걸렸다는 점을 비난할 수밖에 없습니다:P).
원래 질문의 정신에 따라 내 답변을 더 많은 사용 사례에 적용할 수 있도록 이 특정 시나리오에 대해 자세히 논의하고 싶습니다.
다음 입력 파일을 고려하십시오. 실제 업무에서 접할 수 있는 다양한 Edge Case가 가득합니다.현실 세계™ (예: 선행/후행 공백, 공백만으로 구성된 줄, 빈 줄, 하이픈으로 시작하는 줄 [스위치를 도입하는 것으로 해석해서는 안 됨] 등):
lines.txt
a1 a22 a333 a4444
b4444 b333 b22 b1
␠␠c d e f g
␣
hhh
ii jj kk␠
␣
␠␠␠
-L and -x are the gruesome twosome
␣
␣
␣
이전 입력 파일에서는 OPEN BOX
빈 줄을 표시하기 위해 유니코드 문자 U+2423을 사용하고, SYMBOL FOR SPACE
앞뒤 공백을 더 돋보이게 하기 위해 유니코드를 사용했습니다.
내용에 관계없이(내용 없음 포함) 전체적으로 취해 단일 인수로 명령에 전달되는 각 입력 줄에서 명령을 실행한다고 가정합니다. xargs
아래 표시된 대로 이 작업을 수행합니다 (참고: printf
예제 명령이 될 것이며 %q
형식 지정자를 사용하여 제공된 인수가 공백이 있거나 인수가 빈 문자열인 경우 명확성을 위해 아포스트로피로 묶습니다. 모두 입력, 입력만 가능 hhh
) "unscathed" 줄, %q
출력에서 볼 수 있듯이 인쇄할 수 없는 문자가 있는 경우 %q
POSIX $''
인용 구문을 사용하여 이스케이프됩니다.]) :
<lines.txt xargs -n1 -d'\n' printf -- 'Input line: %q\n'
출력은 다음과 같습니다.
Input line: 'a1 a22 a333 a4444'
Input line: 'b4444 b333 b22 b1'
Input line: ' c d e f g'
Input line: ''
Input line: hhh
Input line: 'ii jj kk '
Input line: ''
Input line: ' '
Input line: '-L and -x are the gruesome twosome'
Input line: ''
Input line: ''
Input line: ''
그래서 거기에 있습니다. 이 스위치를 사용하면 인수가 끝나고 다음 인수가 시작되는 위치를 나타내기 위해 -d
입력 파일에서 찾아야 하는 구분 기호를 지정할 수 있습니다 . 그 자체 로 충분히 똑똑하도록 xargs
설정하면 다음과 같이 해석될 수 있습니다.'\n'
xargs
C 스타일 문자 이스케이프-d
해당 페이지의 스위치 설명에 명시된 바와 같이 man
이를 사용하여 xargs
최소한의 노력으로 전체 입력 행을 선택한 명령에 대한 인수로 전달할 수 있습니다.
xargs
또한 이 동작이 필요한 드문 경우에 대해 여러 입력 줄을 연결하고(이 단락 끝에서 자세히 설명할 주의사항과 함께) 다음과 같이 전달하는 데 사용할 수 있다는 점을 언급하고 싶습니다. 우리 명령에 대한 단일 인수입니다. 위의 호출 명령에서 -n
스위치에 전달된 숫자를 프로세스에서 줄 끝이 제거된 xargs
단일 인수로 병합되어야 하는 입력 줄 수를 나타내는 값으로 설정하면 됩니다. \n
불행하게도 이러한 개행 제거 동작은 위의 xargs
접근 방식을 많은 사용 사례에 적합하지 않게 만듭니다. 한 줄이 끝나고 다음 줄이 시작되는 위치를 나타내는 정보가 프로세스에서 손실되기 때문입니다.
답변2
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
답변3
그게 다야 xargs
.
... | xargs command
답변4
GNU Parallel은 이러한 작업을 위해 설계되었습니다. 가장 간단한 사용법은 다음과 같습니다.
cat stuff | grep pattern | parallel java MyProg
자세히 알아보려면 소개 비디오를 시청하세요.http://www.youtube.com/watch?v=OpaiGYxkSuQ