텍스트 처리 필드에서 탭의 길이가 8 자 (기본 길이) 이하인지 알 수있는 방법이 있습니까?
예를 들어, 탭 구분 기호가있는 샘플 파일이 있고 필드 내용이 탭 하나 미만 (≤7)에 맞고 그 뒤에 탭이 있으면 해당 탭은 '탭 크기 – 필드 크기'만됩니다. ' 길이.
한 줄에있는 탭의 총 길이를 얻는 방법이 있습니까? 나는 탭의 수를 찾는 것이 아니라 (즉, 10 개의 탭이 10을 반환해서는 안된다) 그 탭의 문자 길이를 찾는 것입니다.
다음 입력 데이터의 경우 (필드로 구분 된 탭과 하나의 탭만) :
field0 field00 field000 last-field
fld1 fld11 fld001 last-fld
fd2 fld3 last-fld
각 줄의 탭 길이를 계산할 것으로 예상하므로
11
9
9
TAB
문자는 terminal¹에 보낼 때 다음 탭 정지 터미널의 커서 이동을하게 제어 문자입니다. 기본적으로 대부분의 터미널에서 탭 정지는 8 개 열로 떨어져 있지만 구성 할 수 있습니다.
불규칙한 간격으로 탭 정지를 가질 수도 있습니다.
$ tabs 3 9 11; printf '\tx\ty\tz\n'
x y z
터미널 만 TAB이 커서를 이동할 오른쪽 열 수를 알고 있습니다.
탭이 전송되기 전과 후에 터미널에서 커서 위치를 쿼리하여 해당 정보를 얻을 수 있습니다.
주어진 줄에 대해 수동으로 계산하고 해당 줄이 화면의 첫 번째 열에 인쇄되었다고 가정하려면 다음을 수행해야합니다.
\r
(커서를 첫 번째 열로 \b
이동 ) 또는 커서를 뒤로 이동시키는 것과 같은 다른 제어 문자를 처리할지 여부를 결정합니다.탭 정지가 8 개 열마다 있고 행이 화면에 맞으며 터미널에서 제대로 표시 할 수없는 다른 제어 문자 나 문자 (또는 비 문자)가 없다고 가정하면 단순화 할 수 있습니다.
GNU wc
를 사용하면 줄이 다음 위치에 저장됩니다 $line
.
width=$(printf %s "$line" | wc -L)
width_without_tabs=$(printf %s "$line" | tr -d '\t' | wc -L)
width_of_tabs=$((width - width_without_tabs))
wc -L
입력에서 가장 넓은 선의 너비를 제공합니다. wcwidth(3)
문자 너비를 결정하는 데 사용 하고 탭 정지가 8 개 열마다 있다고 가정하여이를 수행합니다.
비 GNU 시스템 및 동일한 가정의 경우 @Kusalananda의 접근 방식을 참조하십시오 . 탭 중지를 지정할 수 있기 때문에 훨씬 더 좋지만 expand
입력에 다중 바이트 문자 또는 0 너비 (문자 결합과 같은) 또는 이중 너비 문자가 포함 된 경우 현재 GNU (적어도)에서 작동하지 않습니다 .
¹ 그렇게 stty tab3
하면 tty 장치 라인 규율이 탭 처리를 대신하고 (터미널로 보내기 전에 커서가있을 수있는 위치에 대한 자체 아이디어에 따라 TAB을 공백으로 변환) 8 개 열마다 탭 정지를 구현합니다. Linux에서 테스트하면 CR, LF 및 BS 문자뿐만 아니라 멀티 바이트 UTF-8 문자 (제공된 iutf8
경우도 켜져 있음)를 올바르게 처리하는 것으로 보이지만 그게 다입니다. 다른 모든 비 제어 문자 (폭이 0 인 문자, 두 배 폭 문자 포함)의 너비가 1이라고 가정하고, (분명히) 이스케이프 시퀀스를 처리하지 않고, 제대로 래핑하지 않습니다. 탭 처리를 할 수 없습니다.
어쨌든 tty 라인 규율은 커서가 어디에 있는지 알아야하며 위의 휴리스틱을 사용합니다. icanon
라인 편집기를 사용할 때 (예 : cat
자체 라인 편집기를 구현하지 않는 응용 프로그램에 텍스트를 입력 할 때) 를 누르면 TabBackspace라인 분야는 표시를 위해 해당 탭 문자 를 지우기 위해 보낼 BS 문자 수를 알아야합니다 . 탭 정지 위치를 변경하면 (예 tabs 12
:) 탭이 제대로 지워지지 않는 것을 알 수 있습니다. 를 누르기 전에 2 바이트 문자를 입력 한 경우에도 동일합니다 TabBackspace.
²이를 위해 탭 문자를 보내고 각 문자 뒤의 커서 위치를 쿼리 할 수 있습니다. 다음과 같은 것 :
tabs=$(
saved_settings=$(stty -g)
stty -icanon min 1 time 0 -echo
gawk -vRS=R -F';' -vORS= < /dev/tty '
function out(s) {print s > "/dev/tty"; fflush("/dev/tty")}
BEGIN{out("\r\t\33[6n")}
$NF <= prev {out("\r"); exit}
{print sep ($NF - 1); sep=","; prev = $NF; out("\t\33[6n")}'
stty "$saved_settings"
)
그런 다음 expand -t "$tabs"
@Kusalananda의 솔루션 을 사용하여 사용할 수 있습니다 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다