스크립트에서 무언가를 찾았지만 주 스크립트에는 속하지 않았습니다. :>
줄 이있었습니다 .
그것이 무엇을 의미하는지 설명해 주시겠습니까?
:> 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은 split
max-fields arg를 사용할 수 있기 때문에 이것을 쉽게 만듭니다 .하지만 awk보다 시작 속도가 훨씬 느립니다.
실제로, 그것은 그렇게 어렵지 않고 작성하기에는 못생긴 정규 표현식으로 판명되었습니다. $5
어색한 대신에 휴식을 취하기 위해 필드를 반복하면 원래 공백이 없어 집니다. 내 첫 번째 가능한 아이디어는 gensub
on $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 에는 스크립트에 던지는 데이터 나 파일 이름에 관계없이 스크립팅에 대한 유용한 정보가 있습니다.