텍스트 파일의 각 줄을 명령에 대한 인수로 구문 분석하는 방법은 무엇입니까?

.txt 파일 이름을 인수로 사용하여 파일 행을 읽는 스크립트를 작성하려고합니다. 예를 들어 command --option "LINE 1"를 실행 한 다음 command --option "LINE 2" 등을 실행합니다. 명령의 출력 다른 파일에 기록됩니다. 어떻게해야합니까? 어디서부터 시작해야할지 모르겠습니다.

답변

while read 루프 사용 :

: > another_file ## Truncate file. while IFS= read -r LINE; do command --option "$LINE" >> another_file done < file 

또 다른 방법은 블록별로 출력을 리디렉션하는 것입니다.

while IFS= read -r LINE; do command --option "$LINE" done < file > another_file 

마지막으로 파일을 여는 것입니다.

exec 4> another_file while IFS= read -r LINE; do command --option "$LINE" >&4 echo xyz ## Another optional command that sends output to stdout. done < file 

명령 중 하나가 입력을 읽는다면 좋을 것입니다. 입력에 다른 fd를 사용하여 명령이 “먹지 않도록”(여기서는 ksh, zsh 또는 bash -u 3, 대신 <&3를 이식 가능하게 사용) :

while IFS= read -ru 3 LINE; do ... done 3< file 

핀 아군이 인수를 수락하려면 다음과 같이 할 수 있습니다.

#!/bin/bash FILE=$1 ANOTHER_FILE=$2 exec 4> "$ANOTHER_FILE" while IFS= read -ru 3 LINE; do command --option "$LINE" >&4 done 3< "$FILE" 

다음과 같이 실행할 수있는 항목 :

bash script.sh file another_file 

추가 아이디어. bash에서는 readarray를 사용합니다.

readarray -t LINES < "$FILE" for LINE in "${LINES[@]}"; do ... done 

참고 : IFS=는 선행 및 후행 공백으로 줄 값을 잘라도 괜찮다면 생략 할 수 있습니다.

답변

또 다른 옵션은 xargs입니다.

GNU 사용 xargs :

xargs -a file -I{} -d"\n" command --option {} other args 

{}는 텍스트 줄의 자리 표시 자입니다.

기타 xargs는 일반적으로 -a, -d가 없지만 일부는 -0. 이를 통해 다음을 수행 할 수 있습니다.

< file tr "\n" "\0" | xargs -0 -I{} command --option {} other args 

Unix 호환 시스템에서 (-I는 POSIX에서 선택 사항이며 UNIX 호환 시스템에 필요), “xargs에서 예상하는 형식으로 행을 인용 하기 위해 입력을 사전 처리해야합니다.

< file sed "s/"/"\\""/g;s/.*/"&"/" | xargs -E "" -I{} command --option {} other args 

그러나 일부 xargs 구현은 인수의 최대 크기에 대해 매우 낮은 제한이 있습니다 (예 : Solaris에서는 255, Unix 사양에서 허용하는 최소값).

댓글

  • <file xargs -L 1 -I{} command --option {} other args
  • 로 축소 가능

  • @iruvar, no, 따옴표를 처리하고 일부 공백을 제거합니다.

답변

정확하게 유지 질문 :

#!/bin/bash # xargs -n param sets how many lines from the input to send to the command # Call command once per line [[ -f $1 ]] && cat $1 | xargs -n1 command --option # Call command with 2 lines as args, such as an openvpn password file # [[ -f $1 ]] && cat $1 | xargs -n2 command --option # Call command with all lines as args # [[ -f $1 ]] && cat $1 | xargs command --option 

댓글

  • 매력처럼 작동했습니다. 🙂
  • +1이 좋아했습니다. 감사합니다.

답변

내가 원하는 최고의 답변 und is :

for i in `cat`; do "$cmd" "$i"; done < $file 

수정 :

… 4 년 후 …

몇 차례의 반대표와 더 많은 경험 끝에 지금 다음을 추천합니다.

xargs -l COMMAND < file 

주석

  • 파일의 각 단어 에 대해 한 번씩 명령을 호출합니다. 또한, 셸 변수에 대한 참조 (do "$cmd" "$i";에서와 같이)를 인용하지 않을 이유가없는 한 항상 인용해야합니다. 파일에 *가 단어로만 포함되어있는 경우 코드는 $cmd *를 실행합니다. 물론 다음과 같이 명령을 실행합니다. 현재 디렉토리의 파일 목록입니다.
  • @ G-Man (zsh 제외), `cat` 이미 *를 확장합니다 (iv id = “를 확장하는 경우 인용되지 않은 $i는 여전히 일부 와일드 카드 (두 번째 라운드)를 확장 할 수 있습니다. 531dfae399 “>

는 일부를 소개합니다). 어쨌든 그 접근 방식은 실제로 잘못되었습니다.

  • +1. 각 줄에 공백없이 사용되는 명령에 필요한 입력 만 포함되어 있으면 정상적으로 작동합니다.
  • +1, xargs 솔루션을 좋아함
  • 이게 작동합니다! (나중에 xargs -l COMMAND < file 수정). 감사합니다!
  • 답변

     sed "s/"/"\\\\""/g;s/.*/\$* "&"/" <<\FILE |\ sh -s -- command echo --option all of the{&}se li$n\es "are safely shell quoted and handed to command as its last argument following --option, and, here, before that echo FILE 

    출력

    --option all of the{&}se li$n\es "are safely shell --option quoted and handed to command as its last argument --option following --option, and, here, before that echo 

    답변

    ed file.txt %g/^/s// / 2,$g/^/-,.j 1s/^/command/ wq chmod 755 file.txt ./file.txt 

    파일의 줄을 지정하고 단일 명령에 인수로 전달합니다. 예 :

    command line1 line2 line3 .... 

    --option 두 번째 명령을 다음과 같이 변경하십시오.

    %g/^/s// --option / 

    주석

    • ed … 정말로?
    • 나는 ' 당신을 비하하지 않았지만 아마도 다음과 같은 이유를 가진 사람이 : (1) 그렇지 않습니다. 질문이 무엇을 요구하는지. 이렇게하면 명령 줄에서 파일의 모든 내용과 함께 명령이 한 번 호출됩니다. 한 줄에 한 번 이 아니라(2) 이것은 쉘에 특수한 문자 (파일에있을 수 있음)를 처리하는 데 아무것도하지 않습니다. 예 : ', ", <, >, ; 등 (3) 불필요한 임시 파일을 생성합니다. (4) 이와 같은 것은 일반적으로 “여기 문서”로 수행됩니다. (5) ed 명령이 어색합니다. 처음 두 명령은 %s/^/ /%j로 줄일 수 있습니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다