Làm cách nào tôi có thể sắp xếp số lượng một dòng các mục được phân tách?


11

Tôi có một dòng (hoặc nhiều dòng) số được phân định bởi một ký tự tùy ý. Tôi có thể sử dụng các công cụ UNIX nào để sắp xếp các mục của từng dòng, giữ lại dấu phân cách?

Những ví dụ bao gồm:

  • danh sách các số; đầu vào : 10 50 23 42; đã sắp xếp10 23 42 50
  • Địa chỉ IP; đầu vào : 10.1.200.42; đã sắp xếp1.10.42.200
  • CSV; đầu vào : 1,100,330,42; đã sắp xếp1,42,100,330
  • giới hạn đường ống; đầu vào : 400|500|404; đã sắp xếp400|404|500

Vì dấu phân cách là tùy ý, vui lòng cung cấp (hoặc mở rộng) Câu trả lời bằng cách sử dụng dấu phân cách một ký tự bạn chọn.


8
bạn nên đăng nó lên trên codegolf :)
ivanivan

1
Có một câu hỏi tương tự ở đây tôi muốn thêm liên kết của nó Các chữ cái trong bảng tên bằng cách sử dụng sort?
αғsнιη

Chỉ là một gợi ý cuthỗ trợ các dấu phân cách tùy ý với -dtùy chọn của nó .
Oleg lobachev

Vui lòng làm rõ liệu bốn ví dụ về DSV đó có trong cùng một tệp hay là các mẫu từ bốn tệp khác nhau.
agc

2
Xem một số ý kiến ​​khác: dấu phân cách là tùy ý, nhưng sẽ được sử dụng nhất quán trong đầu vào. Giả sử trí thông minh về phía nhà sản xuất dữ liệu sao cho họ sẽ không sử dụng dấu phẩy làm dấu phân cách và trong dữ liệu (ví dụ: 4,325 comma 55 comma 42,430sẽ không xảy ra, cũng không 1.5 period 4.2).
Jeff Schaller

Câu trả lời:


12

Bạn có thể đạt được điều này với:

tr '.' '\n' <<<"$aline" | sort -n | paste -sd'.' -

thay thế dấu chấm . bằng dấu phân cách của bạn.
thêm -uvào sortlệnh trên để loại bỏ các bản sao.


hoặc với gawk( GNU awk ) chúng ta có thể xử lý nhiều dòng trong khi ở trên cũng có thể được mở rộng:

gawk -v SEP='*' '{ i=0; split($0, arr, SEP); 
    while ( ++i<=asort(arr) ){ printf("%s%s", i>1?SEP:"", arr[i]) }; 
        print "" 
}' infile

thay thế *như dấu phân cách trường SEP='*'bằng dấu phân cách của bạn .


Lưu ý:
Bạn có thể cần sử dụng -g, --general-numeric-sorttùy chọn sortthay vì -n, --numeric-sortxử lý bất kỳ loại số nào (số nguyên, số float, khoa học, hệ thập lục phân, v.v.).

$ aline='2e-18,6.01e-17,1.4,-4,0xB000,0xB001,23,-3.e+11'
$ tr ',' '\n' <<<"$aline" |sort -g | paste -sd',' -
-3.e+11,-4,2e-18,6.01e-17,1.4,23,0xB000,0xB001

Trong awkkhông thay đổi nhu cầu, nó vẫn sẽ xử lý những.


10

Sử dụng perlcó một phiên bản rõ ràng; phân chia dữ liệu, sắp xếp nó, tham gia lại.

Dấu phân cách cần được liệt kê hai lần (một lần trong splitvà một lần trong join)

ví dụ cho một ,

perl -lpi -e '$_=join(",",sort {$a <=> $b} split(/,/))'

Vì thế

echo 1,100,330,42 | perl -lpi -e '$_=join(",",sort {$a <=> $b} split(/,/))'
1,42,100,330

splitlà một regex, nhân vật có thể cần trích dẫn:

echo 10.1.200.42 | perl -lpi -e '$_=join(".",sort {$a <=> $b} split(/\./))'
1.10.42.200

Bằng cách sử dụng -a-Fcác tùy chọn, có thể loại bỏ phân tách. Với -pvòng lặp, như trước và đặt kết quả $_, nó sẽ tự động in:

perl -F'/\./' -aple '$_=join(".", sort {$a <=> $b} @F)'

4
bạn có thể sử dụng -ltùy chọn thay vì sử dụng chomp. Điều đó cũng thêm lại dòng mới khi in. Xem thêm -a(với -F) cho phần tách.
Stéphane Chazelas

1
Với -l-F, nó thậm chí còn đẹp hơn:perl -F'/\./' -le 'print join(".", sort {$a <=> $b} @F)'
muru

@ StéphaneChazelas cảm ơn vì -llựa chọn này; Tôi đã bỏ lỡ điều đó!
Stephen Harris

1
@muru Tôi không sử dụng -Fcờ ban đầu vì nó không hoạt động chính xác trong tất cả các phiên bản (ví dụ: dòng của bạn trong CentOS 7 - perl 5.16.3 - trả về đầu ra trống, mặc dù nó hoạt động tốt trên Debian 9). Nhưng kết hợp với -pnó cho một kết quả nhỏ hơn một chút, vì vậy tôi đã thêm nó như là một thay thế cho câu trả lời. cho thấy làm thế nào -Fcó thể được sử dụng. Cảm ơn!
Stephen Harris

2
@StephenHarris đó là vì các phiên bản mới hơn của perl sẽ tự động thêm -a-ntùy chọn khi -Fđược sử dụng và -nkhi nào -ađược sử dụng ... vì vậy chỉ cần thay đổi -lethành-lane
Sundeep

4

Sử dụng Python và một ý tưởng tương tự như trong câu trả lời của Stephen Harris :

python3 -c 'import sys; c = sys.argv[1]; sys.stdout.writelines(map(lambda x: c.join(sorted(x.strip().split(c), key=int)) + "\n", sys.stdin))' <delmiter>

Vì vậy, một cái gì đó như:

$ cat foo
10.129.3.4
1.1.1.1
4.3.2.1
$ python3 -c 'import sys; c = sys.argv[1]; sys.stdout.writelines(map(lambda x: c.join(sorted(x.strip().split(c), key=int)) + "\n", sys.stdin))' . < foo
3.4.10.129
1.1.1.1
1.2.3.4

Đáng buồn là phải thực hiện I / O thủ công làm cho điều này kém thanh lịch hơn nhiều so với phiên bản Perl.



3

Vỏ

Tải một ngôn ngữ cấp cao hơn cần có thời gian.
Đối với một vài dòng, chính vỏ có thể là một giải pháp.
Chúng ta có thể sử dụng lệnh bên ngoài sortvà của lệnh tr. Một là khá hiệu quả trong việc sắp xếp các dòng và cái còn lại là hiệu quả để chuyển đổi một dấu phân cách thành dòng mới:

#!/bin/bash
shsort(){
           while IFS='' read -r line; do
               echo "$line" | tr "$1" '\n' |
               sort -n   | paste -sd "$1" -
           done <<<"$2"
    }

shsort ' '    '10 50 23 42'
shsort '.'    '10.1.200.42'
shsort ','    '1,100,330,42'
shsort '|'    '400|500|404'
shsort ','    '3 b,2       x,45    f,*,8jk'
shsort '.'    '10.128.33.6
128.17.71.3
44.32.63.1'

Điều này cần bash vì <<<chỉ sử dụng . Nếu điều đó được thay thế bằng một tài liệu ở đây, giải pháp là hợp lệ cho posix.
Đây là khả năng sắp xếp trường bằng tab, khoảng trống hoặc ký tự vỏ glob ( *, ?, [). Không phải dòng mới vì mỗi dòng đang được sắp xếp.

Thay đổi <<<"$2"để <"$2"xử lý tên tệp và gọi nó như sau:

shsort '.'    infile

Dấu phân cách là giống nhau cho toàn bộ tập tin. Nếu đó là một hạn chế, nó có thể được cải thiện.

Tuy nhiên, một tệp chỉ với 6000 dòng mất 15 giây để xử lý. Quả thực, shell không phải là công cụ tốt nhất để xử lý tệp.

Awk

Đối với nhiều hơn một vài dòng (hơn một vài 10), tốt hơn là sử dụng ngôn ngữ lập trình thực sự. Một giải pháp awk có thể là:

#!/bin/bash
awksort(){
           gawk -v del="$1" '{
               split($0, fields, del)
               l=asort(fields)
               for(i=1;i<=l;i++){
                   printf( "%s%s" , (i==0)?"":del , fields[i] )
               }
               printf "\n"
           }' <"$2"
         }

awksort '.'    infile

Chỉ mất 0,2 giây cho cùng một tệp 6000 dòng được đề cập ở trên.

Hiểu rằng các <"$2"tệp cho có thể được thay đổi trở lại <<<"$2"cho các dòng bên trong các biến shell.

Perl

Giải pháp nhanh nhất là perl.

#!/bin/bash
perlsort(){  perl -lp -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' <<<"$2";   }

perlsort ' '    '10 50 23 42'
perlsort '.'    '10.1.200.42'
perlsort ','    '1,100,330,42'
perlsort '|'    '400|500|404'
perlsort ','    '3 b,2       x,45    f,*,8jk'
perlsort '.'    '10.128.33.6
128.17.71.3
44.32.63.1'

Nếu bạn muốn sắp xếp một thay đổi tệp <<<"$a"thành đơn giản "$a"và thêm -ivào các tùy chọn perl để làm cho phiên bản tệp "tại chỗ":

#!/bin/bash
perlsort(){  perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }

perlsort '.' infile; exit

2

Sử dụng sedđể sắp xếp các octet của một địa chỉ IP

sedkhông có sortchức năng tích hợp, nhưng nếu dữ liệu của bạn bị giới hạn đủ phạm vi (chẳng hạn như với địa chỉ IP), bạn có thể tạo tập lệnh sed thực hiện thủ công một loại bong bóng đơn giản . Cơ chế cơ bản là tìm kiếm các số liền kề không theo thứ tự. Nếu các số không theo thứ tự, trao đổi chúng.

Bản sedthân tập lệnh chứa hai lệnh tìm kiếm và hoán đổi cho mỗi cặp số không theo thứ tự: một cho hai cặp octet đầu tiên (buộc một dấu phân cách xuất hiện để đánh dấu kết thúc của octet thứ ba) và a thứ hai cho cặp octet thứ ba (kết thúc bằng EOL). Nếu giao dịch hoán đổi xảy ra, chương trình sẽ phân nhánh đến đỉnh của tập lệnh, tìm kiếm các số không theo thứ tự. Nếu không, nó thoát.

Kịch bản được tạo ra, một phần:

$ head -n 3 generated.sed
:top
s/255\.254\./254.255./g; s/255\.254$/254.255/
s/255\.253\./253.255./g; s/255\.253$/253.255/

# ... middle of the script omitted ...

$ tail -n 4 generated.sed
s/2\.1\./1.2./g; s/2\.1$/1.2/
s/2\.0\./0.2./g; s/2\.0$/0.2/
s/1\.0\./0.1./g; s/1\.0$/0.1/
ttop

Cách tiếp cận này mã hóa thời gian là dấu phân cách, phải được thoát, vì nếu không nó sẽ là "đặc biệt" đối với cú pháp biểu thức chính quy (cho phép bất kỳ ký tự nào).

Để tạo một tập lệnh sed như vậy, vòng lặp này sẽ làm:

#!/bin/bash

echo ':top'

for (( n = 255; n >= 0; n-- )); do
  for (( m = n - 1; m >= 0; m-- )); do
    printf '%s; %s\n' "s/$n\\.$m\\./$m.$n./g" "s/$n\\.$m\$/$m.$n/"
  done
done

echo 'ttop'

Chuyển hướng đầu ra của tập lệnh đó sang tập tin khác, nói sort-ips.sed.

Một lần chạy mẫu có thể trông giống như:

ip=$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256)).$((RANDOM % 256))
printf '%s\n' "$ip" | sed -f sort-ips.sed

Biến thể sau đây trên tập lệnh tạo sử dụng các dấu biên giới từ \<\>để loại bỏ nhu cầu thay thế thứ hai. Điều này cũng cắt giảm kích thước của tập lệnh được tạo từ 1,3 MB xuống dưới 900 KB cùng với việc giảm đáng kể thời gian chạy của sedchính nó (xuống khoảng 50% -75% so với bản gốc, tùy thuộc vào việc sedtriển khai nào đang được sử dụng):

#!/bin/bash

echo ':top'

for (( n = 255; n >= 0; --n )); do
  for (( m = n - 1; m >= 0; --m )); do
      printf '%s\n' "s/\\<$n\\>\\.\\<$m\\>/$m.$n/g"
  done
done

echo 'ttop'

1
Một ý tưởng thú vị, nhưng nó dường như quá phức tạp hóa mọi thứ một chút.
Matt

1
@Matt Đó là một điểm. Sắp xếp mọi thứ với sedthật lố bịch, đó là lý do tại sao đó là một thử thách thú vị.
Kusalananda

2

Ở đây một số bash đoán chính dấu phân cách:

#!/bin/bash

delimiter="${1//[[:digit:]]/}"
if echo $delimiter | grep -q "^\(.\)\1\+$"
then
  delimiter="${delimiter:0:1}"
  if [[ -z $(echo $1 | grep "^\([0-9]\+"$delimiter"\([0-9]\+\)*\)\+$") ]]
  then
    echo "You seem to have empty fields between the delimiters."
    exit 1
  fi
  if [[ './\' == *$delimiter* ]]
  then
    n=$( echo $1 | sed "s/\\"$delimiter"/\\n/g" | sort -n | tr '\n' ' ' | sed -e "s/\\s/\\"$delimiter"/g")
  else
    n=$( echo $1 | sed "s/"$delimiter"/\\n/g" | sort -n | tr '\n' ' ' | sed -e "s/\\s/"$delimiter"/g")
  fi
  echo ${n%$delimiter}
  exit 0
else
  echo "The string does not consist of digits separated by one unique delimiter."
  exit 1
fi

Nó có thể không rất hiệu quả cũng không sạch sẽ nhưng nó hoạt động.

Sử dụng như thế nào bash my_script.sh "00/00/18/29838/2".

Trả về một lỗi khi cùng một dấu phân cách không được sử dụng nhất quán hoặc khi hai hoặc nhiều dấu phân cách đi theo nhau.

Nếu dấu phân cách được sử dụng là một ký tự đặc biệt thì nó được thoát (nếu không sedsẽ trả về lỗi).


Điều đó đã truyền cảm hứng cho điều này .
agc

2

Câu trả lời này dựa trên sự hiểu lầm về Q., nhưng trong một số trường hợp, dù sao nó cũng đúng. Nếu đầu vào là số hoàn toàn tự nhiên và chỉ có một dấu phân cách trên mỗi dòng, (như với dữ liệu mẫu trong Q.), thì nó hoạt động chính xác. Nó cũng sẽ xử lý các tệp có dòng mà mỗi dòng có dấu phân cách riêng, nhiều hơn một chút so với yêu cầu.

Hàm shell này reads từ đầu vào tiêu chuẩn, sử dụng thay thế tham số POSIX để tìm dấu phân cách cụ thể trên mỗi dòng, (được lưu trữ $d) và sử dụng trđể thay thế $dbằng một dòng mới \nsorts dữ liệu của dòng đó, sau đó khôi phục các dấu phân cách ban đầu của mỗi dòng:

sdn() { while read x; do
            d="${x#${x%%[^0-9]*}}"   d="${d%%[0-9]*}"
            x=$(echo -n "$x" | tr "$d" '\n' | sort -g | tr '\n' "$d")
            echo ${x%?}
        done ; }

Áp dụng cho dữ liệu được cung cấp trong OP :

printf "%s\n" "10 50 23 42" "10.1.200.42" "1,100,330,42" "400|500|404" | sdn

Đầu ra:

10 23 42 50
1.10.42.200
1,42,100,330
400|404|500

Dấu phân cách trong bất kỳ dòng nào sẽ nhất quán; các giải pháp chung cho phép người dùng khai báo dấu phân cách là tuyệt vời, nhưng câu trả lời có thể giả sử bất kỳ dấu phân cách nào có ý nghĩa đối với họ (ký tự đơn và không có trong dữ liệu số).
Jeff Schaller

2

Đối với các dấu phân cách tùy ý:

perl -lne '
  @list = /\D+|\d+/g;
  @sorted = sort {$a <=> $b} grep /\d/, @list;
  for (@list) {$_ = shift@sorted if /\d/};
  print @list'

Trên một đầu vào như:

5,4,2,3
6|5,2|4
There are 10 numbers in those 3 lines

Nó cho:

2,3,4,5
2|4,5|6
There are 3 numbers in those 10 lines

0

Điều này sẽ xử lý bất kỳ dấu phân cách không chữ số (0-9). Thí dụ:

x='1!4!3!5!2'; delim=$(echo "$x" | tr -d 0-9 | cut -b1); echo "$x" | tr "$delim" '\n' | sort -g | tr '\n' "$delim" | sed "s/$delim$/\n/"

Đầu ra:

1!2!3!4!5

0

Với perl:

$ # -a to auto-split on whitespace, results in @F array
$ echo 'foo baz v22 aimed' | perl -lane 'print join " ", sort @F'
aimed baz foo v22
$ # {$a <=> $b} for numeric comparison, {$b <=> $a} will give descending order
$ echo '1,100,330,42' | perl -F, -lane 'print join ",", sort {$a <=> $b} @F'
1,42,100,330

Với ruby, có phần giống vớiperl

$ # -a to auto-split on whitespace, results in $F array
$ # $F is sorted and then joined using the given string
$ echo 'foo baz v22 aimed' | ruby -lane 'print $F.sort * " "'
aimed baz foo v22

$ # (&:to_i) to convert string to integer
$ echo '1,100,330,42' | ruby -F, -lane 'print $F.sort_by(&:to_i) * ","'
1,42,100,330

$ echo '10.1.200.42' | ruby -F'\.' -lane 'print $F.sort_by(&:to_i) * "."'
1.10.42.200


Lệnh tùy chỉnh và chỉ truyền chuỗi phân cách (không phải regex). Sẽ hoạt động nếu đầu vào có dữ liệu nổi quá

$ # by default join uses value of $,
$ sort_line(){ ruby -lne '$,=ENV["d"]; print $_.split($,).sort_by(&:to_f).join' ; }

$ s='103,14.5,30,24'
$ echo "$s" | d=',' sort_line
14.5,24,30,103
$ s='10.1.200.42'
$ echo "$s" | d='.' sort_line
1.10.42.200

$ # for file input
$ echo '123--87--23' > ip.txt
$ echo '3--12--435--8' >> ip.txt
$ d='--' sort_line <ip.txt
23--87--123
3--8--12--435


Lệnh tùy chỉnh cho perl

$ sort_line(){ perl -lne '$d=$ENV{d}; print join $d, sort {$a <=> $b} split /\Q$d/' ; }
$ s='123^[]$87^[]$23'
$ echo "$s" | d='^[]$' sort_line 
23^[]$87^[]$123


Đọc thêm - Tôi đã có danh sách tiện dụng này về các lớp lót perl / ruby


0

Sau đây là một biến thể về câu trả lời của Jeff theo nghĩa là nó tạo ra một sedkịch bản sẽ thực hiện sắp xếp Bong bóng, nhưng đủ khác nhau để đảm bảo câu trả lời của chính nó.

Sự khác biệt là thay vì tạo các biểu thức chính quy cơ bản O (n ^ 2), điều này tạo ra các biểu thức chính quy mở rộng O (n). Kịch bản kết quả sẽ có kích thước lớn khoảng 15 KB. Thời gian chạy của sedtập lệnh là theo phân số của một giây (mất một chút thời gian để tạo tập lệnh).

Nó bị giới hạn trong việc sắp xếp các số nguyên dương được phân tách bằng các dấu chấm, nhưng nó không giới hạn kích thước của các số nguyên (chỉ tăng 255trong vòng lặp chính) hoặc số lượng số nguyên. Dấu phân cách có thể được thay đổi bằng cách thay đổi delim='.'mã.

Tôi đã hoàn thành công việc của mình để có được các biểu thức chính quy, vì vậy tôi sẽ để lại mô tả chi tiết cho một ngày khác.

#!/bin/bash

# This function creates a extended regular expression
# that matches a positive number less than the given parameter.
lt_pattern() {
    local n="$1"  # Our number.
    local -a res  # Our result, an array of regular expressions that we
                  # later join into a string.

    for (( i = 1; i < ${#n}; ++i )); do
        d=$(( ${n: -i:1} - 1 )) # The i:th digit of the number, from right to left, minus one.

        if (( d >= 0 )); then
            res+=( "$( printf '%d[0-%d][0-9]{%d}' "${n:0:-i}" "$d" "$(( i - 1 ))" )" )
        fi
    done

    d=${n:0:1} # The first digit of the number.
    if (( d > 1 )); then
        res+=( "$( printf '[1-%d][0-9]{%d}' "$(( d - 1 ))" "$(( ${#n} - 1 ))" )" )
    fi

    if (( n > 9 )); then
        # The number is 10 or larger.
        res+=( "$( printf '[0-9]{1,%d}' "$(( ${#n} - 1 ))" )" )
    fi

    if (( n == 1 )); then
        # The number is 1. The only thing smaller is zero.
        res+=( 0 )
    fi

    # Join our res array of expressions into a '|'-delimited string.
    ( IFS='|'; printf '%s\n' "${res[*]}" )
}

echo ':top'

delim='.'

for (( n = 255; n > 0; --n )); do
    printf 's/\\<%d\\>\\%s\\<(%s)\\>/\\1%s%d/g\n' \
        "$n" "$delim" "$( lt_pattern "$n" )" "$delim" "$n"
done

echo 'ttop'

Kịch bản sẽ trông giống như thế này:

$ bash generator.sh >script.sed
$ head -n 5 script.sed
:top
s/\<255\>\.\<(25[0-4][0-9]{0}|2[0-4][0-9]{1}|[1-1][0-9]{2}|[0-9]{1,2})\>/\1.255/g
s/\<254\>\.\<(25[0-3][0-9]{0}|2[0-4][0-9]{1}|[1-1][0-9]{2}|[0-9]{1,2})\>/\1.254/g
s/\<253\>\.\<(25[0-2][0-9]{0}|2[0-4][0-9]{1}|[1-1][0-9]{2}|[0-9]{1,2})\>/\1.253/g
s/\<252\>\.\<(25[0-1][0-9]{0}|2[0-4][0-9]{1}|[1-1][0-9]{2}|[0-9]{1,2})\>/\1.252/g
$ tail -n 5 script.sed
s/\<4\>\.\<([1-3][0-9]{0})\>/\1.4/g
s/\<3\>\.\<([1-2][0-9]{0})\>/\1.3/g
s/\<2\>\.\<([1-1][0-9]{0})\>/\1.2/g
s/\<1\>\.\<(0)\>/\1.1/g
ttop

Ý tưởng đằng sau các biểu thức chính quy được tạo là khớp mẫu cho các số nhỏ hơn mỗi số nguyên; hai số đó sẽ không theo thứ tự và do đó được hoán đổi. Các biểu thức chính quy được nhóm thành một số tùy chọn HOẶC. Hãy chú ý đến các phạm vi được thêm vào từng mục, đôi khi chúng là {0}, có nghĩa là mục ngay trước đó sẽ bị bỏ qua khỏi tìm kiếm. Các tùy chọn regex, từ trái sang phải, khớp các số nhỏ hơn số đã cho bằng cách:

  • những nơi
  • hàng chục
  • hàng trăm nơi
  • (tiếp tục khi cần thiết, cho số lượng lớn hơn)
  • hoặc bằng cách nhỏ hơn về độ lớn (số chữ số)

Để đánh vần một ví dụ, hãy lấy 101(có thêm khoảng trắng để dễ đọc):

s/ \<101\> \. \<(10[0-0][0-9]{0} | [0-9]{1,2})\> / \1.101 /g

Ở đây, sự xen kẽ đầu tiên cho phép các số từ 100 đến 100; sự xen kẽ thứ hai cho phép 0 đến 99.

Một ví dụ khác là 154:

s/ \<154\> \. \<(15[0-3][0-9]{0} | 1[0-4][0-9]{1} | [0-9]{1,2})\> / \1.154 /g

Ở đây tùy chọn đầu tiên cho phép 150 đến 153; cái thứ hai cho phép 100 đến 149, và cái cuối cùng cho phép từ 0 đến 99.

Kiểm tra bốn lần trong một vòng lặp:

for test_run in {1..4}; do
    nums=$(( RANDOM%256 )).$(( RANDOM%256 )).$(( RANDOM%256 )).$(( RANDOM%256 ))
    printf 'nums=%s\n' "$nums"
    sed -E -f script.sed <<<"$nums"
done

Đầu ra:

nums=90.19.146.232
19.90.146.232
nums=8.226.70.154
8.70.154.226
nums=1.64.96.143
1.64.96.143
nums=67.6.203.56
6.56.67.203

-2

Chia đầu vào thành nhiều dòng

Sử dụng tr, bạn có thể chia đầu vào bằng cách sử dụng một dấu phân cách tùy ý thành nhiều dòng.

Đầu vào này sau đó có thể được chạy qua sort(sử dụng -nnếu đầu vào là số).

Nếu bạn muốn giữ lại dấu phân cách trong đầu ra, thì bạn có thể sử dụng trlại để thêm lại dấu phân cách.

ví dụ: sử dụng không gian như một dấu phân cách

cat input.txt | tr " " "\n" | sort -n | tr "\n" " "

đầu vào: 1 2 4 1 4 32 18 3 đầu ra:1 1 2 3 4 4 18 32


Bạn có thể giả định một cách an toàn các mục số và có: nên thay thế dấu phân cách.
Jeff Schaller
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.