bash에서이 이상한 기호“:>”는 무엇을 의미합니까?


47

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

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

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

6
중요한 :>것은 단일 연산자가 아닙니다. : > file대신 읽는다면 이해하기가 더 쉬울 수 있습니다 .
jpfx1342

스크립트를 작성하는 사람이 루프의 출력을 파일로 경로 재 지정했음을 의미합니다 while read A B C D E; do echo "$A;$B;$D;$E;$C"; done < otherfile > file. 또는 Peter가 제안한대로 awk가 업무에 적합한 도구를 사용해야했습니다 . 따로, 거의 항상 -r스위치를 스위치와 함께 사용하려고합니다read .
Tom Fenech

강타 밖에서는 까마귀에게는 스마일입니다.
smci

답변:


46

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

:> file

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

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

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

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

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


나는 두 번째 줄을 이해하지 못한다. 나는 읽기 변수를 읽는다고 생각했습니다. 에코 명령도 이상합니다. 설명해 주시겠습니까?
diego9403

나는 유닉스 전문가가 아니에요하지만 난 두 번째 라인에서 일을 읽고 생각 otherfile하고 echo그들을 밖으로이야 file. 그것은 또한 읽은 내용에서 변수를 만듭니다 ... 명확한 답변을 원한다면 자신의 질문을하십시오.
DavidPostill

2
@ diego9403 : readstdin에서 입력을받습니다. 자체적으로 입력 한 내용을 읽습니다. stdin이 경로 재 지정되었으므로 <otherfile내용은 otherfilestdin으로 "입력"됩니다. 따라서 read값을 한 줄씩 변수 $ A, $ B, $ C, $ D 및 $ E로 가져옵니다.
slebetman

그렇다면 truncatecoreutils 보다 더 모호한 대안 입니까?
Federico Poloni

1
@PeterCordes 나는 "흔하지 않다"에서처럼 "모호하지 않다"는 말이 아니라 "독자에게 덜 명확하다"는 의미를 가졌다.
Federico Poloni

29

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

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

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

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


2
파일이 이미 존재하는 경우에도 파일이 잘립니다.
DavidPostill

2
예, 이것은 무엇을 >합니까
ARKADIUSZ Drabczyk

2
:의 줄임말입니다 true. 아마도 일부 껍질 true에 내장되어 있지 않습니까? 둘 다 bash에 내장되어 있습니다.
Peter Cordes

12

:의 다른 이름입니다 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 에는 스크립트에 던지는 데이터 나 파일 이름에 관계없이 스크립팅에 대한 유용한 정보가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.