bash에서이 이상한 기호“:>”는 무엇을 의미합니까? 의미하는지 설명해 주시겠습니까? :> file while read A B

스크립트에서 무언가를 찾았지만 주 스크립트에는 속하지 않았습니다. :>줄 이있었습니다 .

그것이 무엇을 의미하는지 설명해 주시겠습니까?

:> file
while read A B C D E; do echo "$A;$B;$D;$E;$C" >> file; done < otherfile



답변

bash 스크립트 줄에 :>가있었습니다. 무슨 뜻인가요?

:> file

그것은 바로 말하기 방법입니다.

  • file존재하지 않는 경우 0바이트 를 작성하십시오 .

즉, file존재하고 비어 있는지 확인할 수 있습니다 .

사용할 수도 > file있지만 :> file휴대 성이 더 좋습니다.

스택 오버플로 질문을 참조하십시오. ‘:'(콜론) GNU Bash Builtin의 목적은 무엇입니까? 자세한 내용은.


답변

새 파일을 만드는 멋진 방법처럼 보입니다. In bash :은 널 명령입니다.

$ type :
: is a shell builtin
$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

>출력을 :파일로 리디렉션 합니다.


답변

:의 다른 이름입니다 true. 모두 bash는 쉘 내장 명령 없다,하지만 거기 /bin/:/bin/true. 출력 리디렉션은을 사용하여 셸을 open(2)파일로 보냅니다 O_CREAT|O_TRUNC. 아무 것도 쓰지 않으면 길이가 0입니다.

이 두 조각을 합치 :> file는 것은 파일을 잘리는 관용구입니다. 그러나 대부분의 사람들은을 작성하여 덜 이상하게 보이려고 노력할 것 : >file입니다.


두 번째 줄에 대한 의견을 요청 했으므로 의견을 답변으로 바꾸겠습니다. (당신이 당신의 질문에 이것을 묻지 않았더라도)

두 번째 줄은 otherfile이름이 지정된 변수로 줄을 읽는 루프입니다 . 루프 바디는 이전의 공백 대신 구분 기호 echo로 인쇄합니다 ;. file리디렉션이 루프 내부에 있기 때문에 각 반복이 닫히고 다시 열립니다 (추가 용). 를 사용하면 속도 while ...;do read -r ...;done <otherfile >file가 줄어들고 파일을 먼저자를 필요가 없습니다. 탈출 캐릭터로 read -r먹지 않습니다 \.

bash에서의 텍스트 처리는 상당히 느립니다. read그중 일부는 피할 수 없습니다. 한 줄에 한 바이트 read(2)씩 (바이트 당 한 번의 시스템 호출) 행의 오버 슈트를 피해야합니다. 작업에 적합한 도구를 사용하는 것이 좋습니다.

awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile  >file

--otherfile바보 같은 이름을 가진 경우 스크립트가 중단되지 않음을 의미합니다 --version.

출력 필드 구분 기호를 설정하면 ;여러 필드를 인자로 전달하여 인쇄 할 수 있습니다. 셸 read은 공백이있는 줄의 나머지 부분을 마지막 변수에 할당하지만 awk에게 5로만 나누도록 지시하는 방법은 없습니다. 중요하면 bash 루프를 사용하십시오. 왜냐하면 awk에서는 불편하기 때문입니다. Perl은 splitmax-fields arg를 사용할 수 있기 때문에 이것을 쉽게 만듭니다 .하지만 awk보다 시작 속도가 훨씬 느립니다.

실제로, 그것은 그렇게 어렵지 않고 작성하기에는 못생긴 정규 표현식으로 판명되었습니다. $5어색한 대신에 휴식을 취하기 위해 필드를 반복하면 원래 공백이 없어 집니다. 내 첫 번째 가능한 아이디어는 gensubon $0(전체 줄)을 사용하여 처음 4 개의 필드 (즉 공백이 아닌 뒤에 공백이 있음)를 제거하고 다른 모든 것을 남기는 것입니다.

awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file

첫 번째 시도에서 올바르게 얻었지만 그 사실에 감명 받았다는 사실은 그 awk 코드의 가독성에 관한 것입니다. >. <

print이전 과 동일 하지만 tail대신에 어떻게 표시되는지 확인하십시오 $5.

echo 'A  B c DD    e      f g    f' |
  awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
   print $1, $2, $4, tail, $3 }'

A;B;DD;e       f g    f;c

리터럴을 복사 / 붙여 넣기하여 출력에서 ​​나온 것을 보여줄 수 있다면 더 인상적입니다. ^ Q와 함께 bash에 1을 입력하십시오. ctrl-Q는 bash의 emacs 스타일 라인 편집이 실제 emacs와 동일하므로 다음 키 누르기를 리터럴 문자로 인용합니다.

http://mywiki.wooledge.org/BashFAQ 에는 스크립트에 던지는 데이터 나 파일 이름에 관계없이 스크립팅에 대한 유용한 정보가 있습니다.


답변