リストを特定の文字と並べ替えるには?

リストを特定の文字と並べ替えるには?

任意の文字を含むテキスト行を水平方向に並べ替えるために使用できる一連のコマンドまたはコマンドはありますか?たとえば、電子メールアドレスリストの場合、出力はすべての「@」文字が縦に並べられたテキストファイルを生成します。

成功するには、ほとんどの行の先頭に可変量のスペースを追加する必要があると思います。読むためにもっと努力が必要なので、別の列を望まない(例column -t -s "@" < file.txt:)。

今後:

[email protected]
[email protected]
[email protected]

後ろに:

   [email protected]
[email protected]
 [email protected]

つまり、文字をアンカーポイントとして指定し、周囲のテキストをそのアンカーポイントを中心に水平中央に配置できますか?マイユースケースは、視覚的なスキャンを簡単にするためのEメールアドレスです。

答え1

最も簡単には、最初のフィールドを適切に広いフィールド幅で印刷できます。

awk -F@ 'BEGIN{OFS=FS} {$1 = sprintf("%12s", $1)} 1' file
         [email protected]
      [email protected]
       [email protected]

私が知る限り、特定の最大フィールド幅を仮定しない方法は、ファイルをメモリに保持するか、2回のパスを実行する必要があります。

答え2

ハッキーソリューションは入力テキストについて多くの仮定をします。

$ # 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/'
     [email protected]
  [email protected]
   [email protected]

答え3

可能な限り短いパディング長を使用して区切り文字の左側にあるすべての文字列を右揃えするクイック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

答え4

別のGNUawk+column解決策:

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

出力:

   [email protected]
[email protected]
 [email protected]

関連情報