विशिष्ट चरित्र के लिए सूची को कैसे संरेखित करें?


13

क्या कोई ऐसी कमांड या सेट है जिसे मैं टेक्स्ट का क्षैतिज रूप से संरेखित करने के लिए उपयोग कर सकता है एक मनमाना चरित्र? उदाहरण के लिए, ईमेल पतों की एक सूची के साथ आउटपुट सभी '@' वर्णों के साथ एक पाठ फ़ाइल का निर्माण करेगा, जो लंबवत रूप से पंक्तिबद्ध है।

सफल होने के लिए मेरा मानना ​​है कि अधिकांश लाइनों की शुरुआत में रिक्त स्थानों की एक चर संख्या को जोड़ा जाना चाहिए। मुझे अलग कॉलम नहीं चाहिए क्योंकि वे पढ़ने के लिए अधिक प्रयास करते हैं (उदाहरण के लिए, 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

अलग तरीके से रखें: क्या मैं एक एंकर बिंदु होने के लिए एक चरित्र निर्दिष्ट कर सकता हूं, जिसके आसपास का पाठ क्षैतिज रूप से केंद्रित है? इसके लिए मेरा उपयोग-मामला ईमेल पते हैं, जिससे उन्हें नेत्रहीन स्कैन करना आसान हो जाता है।


1
यदि कई @प्रतीक हैं तो क्या होना चाहिए ?
जेटा

अच्छा सवाल, कई @प्रतीकों को ईमेल पते के साथ कोई मुद्दा नहीं होना चाहिए , लेकिन एक उपयोगकर्ता को प्रति पंक्ति एक चरित्र का चयन करने में सक्षम होना चाहिए जिसमें 'एंकर' हो, जिसके चारों ओर दूसरा पाठ केंद्रित हो।
टॉम ब्रॉसमैन

1
@ईमेल पते में कई प्रतीकों की अनुमति है, जैसे tom"@brossmann"@example.com। इसीलिए मैंने पूछा कि अगर कई @चिन्ह हों तो क्या होना चाहिए :)।
ज़ीटा

@Zeta कई @प्रतीकों को कई ईमेल सेवाओं में अनुमति नहीं है। यह "सामान्य" ईमेलों की अपेक्षा करना पूरी तरह से उचित है जो "वास्तविक" एक की तुलना में एक सख्त मानक फिट करते हैं, जब तक कि आप कच्चे, अनफ़िल्टर्ड उपयोगकर्ता इनपुट के साथ काम नहीं कर रहे हैं, उस स्थिति में जब आप लाइनों के साथ सौदा नहीं करने की अधिक संभावना रखते हैं @
निधि मोनिका का मुकदमा

जवाबों:


3

सं अवाक। केवल sedऔर column:

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

आउटपुट:

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

अब, मुझे लगता है कि, यह लगभग सुदीप के समाधान के समान है, यह सिर्फ कम दिखता है / के पास कम कॉल हैं sed, और यह भी मानता है कि @प्रत्येक पंक्ति में केवल एक बार होता है।


1
यह और भी कम हो सकता है:column -ts@ input.txt | sed -r 's/([^ ]+)( *)\s\s/\2\1@/'
मिनीमैक्स

11

इसके सरलतम रूप में, आप पहले क्षेत्र को एक उपयुक्त बड़े क्षेत्र के उदाहरण में प्रिंट कर सकते हैं

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

AFAIK किसी भी विधि है कि एक विशिष्ट अधिकतम क्षेत्र ग्रहण नहीं करता है या तो फ़ाइल को स्मृति में रखने या दो पास बनाने की आवश्यकता होगी।


अच्छा है, लंबाई पाने के लिए कोई भी इस्तेमाल कर सकता है cw=$(cut -d@ -f1 file | wc -L)और फिरawk -v w="$cw" 'BEGIN{OFS=FS="@"} {$1 = sprintf("%*s", w, $1)} 1'
Sundeep

328 पतों की सूची के खिलाफ यह परीक्षण, दस किसी तरह आउटपुट (अब 318 लाइनों) से गायब हैं। स्पष्टता के लिए, मैं भाग गया awk -F@ '{a[$1] = $2; w = length($1) > w? length($1) : w; next} END {for (i in a) printf("%*s%c%s\n", w, i, FS, a[i])}' INPUT-FILE.txt > OUT.txt। इसने शेष भाग को अच्छी तरह से प्रारूपित किया, लेकिन कुछ डेटा गायब है।
टॉम ब्रॉसमैन

1
@TomBrossman धन्यवाद मैं सिर्फ महसूस किया कि यह काफी गंभीर दोष है - यह समान नाम फ़ील्ड संभाल नहीं होगा - मुझे लगता है कि एक को हटाने के लिए जा रहा हूँ
steeldriver

वही परिणाम, लेकिन अधिक संक्षेप मेंawk -F@ '{printf "%12s@%s\n", $1, $2}' input.txt
मिनीमैक्स

6

हैकी समाधान, इनपुट पाठ के बारे में बहुत कुछ मानता है

$ # 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

4

एक त्वरित पायथन समाधान जो सबसे कम संभव गद्दी की लंबाई का उपयोग करता है जो विभाजक के सभी तारों को दाएं-संरेखित करता है:

#!/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

2

एक और 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

क्या आप इस बारे में कुछ जोड़ सकते हैं कि यह कैसे काम करता है?
जो

2

यह बैश स्ट्रिंग हेरफेर के साथ भी काम कर सकता है।

बैश स्क्रिप्ट (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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.