목록을 특정 문자에 맞추는 방법? 노력이 필요하기

텍스트 줄을 임의의 문자에 가로로 맞추는 데 사용할 수있는 명령 또는 명령 집합이 있습니까? 예를 들어, 전자 메일 주소 목록을 사용하면 모든 ‘@’문자가 세로로 정렬 된 텍스트 파일이 출력됩니다.

성공하기 위해서는 대부분의 줄의 시작 부분에 가변 수의 빈 공간을 추가해야한다고 생각합니다. 읽기에 더 많은 노력이 필요하기 때문에 별도의 열을 원하지 않습니다 (예 🙂 column -t -s "@" < file.txt.

전에:

123@example.com
456789@example.net
01234@something-else.com

후:

   123@example.com
456789@example.net
 01234@something-else.com

달리 말하면 : 문자를 앵커 포인트로 지정할 수 있습니까? 주변 텍스트가 가로로 가운데에 위치합니까? 이것에 대한 나의 유스 케이스는 시각적으로 쉽게 스캔 할 수 있도록 이메일 주소입니다.



답변

어 A 지 만 sedcolumn:

column -ts@ file.txt | sed -E 's/([^ ]+)([ ]+) (.+)/\2\1@\3/'

산출:

   123@example.com
456789@example.net
 01234@something-else.com

이제 생각합니다. 이것은 Sundeep 솔루션과 거의 동일하며 짧아 보이며 호출 횟수가 적 으며 각 라인에서 한 번만 발생 sed한다고 가정합니다 @.


답변

가장 간단한 방법으로 첫 번째 필드를 적절하게 큰 필드 너비로 인쇄 할 수 있습니다.

awk -F@ 'BEGIN{OFS=FS} {$1 = sprintf("%12s", $1)} 1' file
         123@example.com
      456789@example.net
       01234@something-else.com

AFAIK 특정 최대 필드 너비를 가정하지 않는 방법은 파일을 메모리에 보관하거나 두 번 통과해야합니다.


답변

해키 솔루션, 입력 텍스트에 대해 많은 가정

$ # four commas to reduce chance of it affecting actual email address
$ sed 's/@/,,,,@/' ip.txt | column -t -s,,,,
123     @example.com
456789  @example.net
01234   @something-else.com

$ sed 's/@/,,,,@/' ip.txt | column -t -s,,,, | sed -E 's/^([^ ]+)( +)/\2\1/'
     123@example.com
  456789@example.net
   01234@something-else.com

답변

구분 기호의 왼쪽에있는 모든 문자열을 오른쪽 정렬하는 가능한 가장 짧은 패딩 길이를 사용하는 빠른 Python 솔루션 :

#!/usr/bin/env python3
import sys
fieldsep = '@'
records = [line.rstrip('\n').split(fieldsep, 1) for line in sys.stdin]
col1_len = max((len(r[0]) for r in records), default=0)
for r in records:
    print(r[0].rjust(col1_len), r[1], sep=fieldsep)

용법:

python3 align-field.py < data.txt

답변

또 다른 GNU awk+ column솔루션 :

awk '{ split($0,a,/ +/,sep); printf "%*s@%s\n",length($1 sep[1])-2,$1,$2 }' <(column -ts'@' file)

출력 :

   123@example.com
456789@example.net
 01234@something-else.com

답변

이것은 Bash 문자열 조작에서도 작동합니다.

배쉬 스크립트 (4.x) :

#!/bin/bash

read -d '' -r -a data <"data.txt"

for ((pos=0, i=0; i<${#data[@]}; i++)); do
    locl=${data[$i]%@*}                         # The local-part.
    [[ ${#locl} -gt $pos ]] && pos=${#locl}     # Determine the lengthiest $locl.
done

for ((i=0; i<${#data[@]}; i++)); do
    email=${data[$i]}
    locl=${email%@*}                            # The local-part.
    domain=${email#*@}                          # The email domain.
    printf '%*s@%s\n' $pos $locl $domain        # Align $locl to the right, at $pos.
done

결과:

   123@example.com
456789@example.net
 01234@something-else.com