基于其中一行中的单个字段对线对进行排序

时间:2017-08-23 16:20:56

标签: bash shell sed bsd

我试图改变像:

这样的流
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8

分为:

#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8

...通过对以#开头的行的第二个以逗号分隔的字段进行排序,同时将其他行与带有排序键的行重新排序。

所以我只对包含"#EXTINF"的行进行排序。并从","之后排序。它还应该保持下面的行(URL行)与它的排序行。

3 个答案:

答案 0 :(得分:1)

将数据转换为易于排序的格式,然后对其进行排序。所以:

to_one_line_per_record() {
  local inf_line= line=
  while read -r line; do
    if [[ $line = "#"* ]]; then
      inf_line=$line
    else
      printf '%s\n' "${inf_line},$line"
    fi
  done
}

from_one_line_per_record() {
  local inf_f1 inf_f2 url
  while IFS=, read -r inf_f1 inf_f2 url; do
    printf '%s,%s\n%s\n' "$inf_f1" "$inf_f2" "$url"
  done
}

to_one_line_from_record | sort -t, -k2,2 | from_one_line_per_record

根据您的输入,to_one_line_per_record的输出为:

#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC,http://AnotherStreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD,http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery,http://DisStreamUrl.m3u8

通过sort -t, -k2,2传递,输出变为:

#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD,http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery,http://DisStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC,http://AnotherStreamUrl.m3u8

传递给from_one_line_per_record,它会转换为:

#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8

答案 1 :(得分:1)

这是一个使用GNU awk的asort

$ awk '
BEGIN { FS="," }                     # define , as field separator
{
    p=( NR%2 ? $2 : p )              # every other record updates p
    a[p]=a[p] (a[p]==""?"":ORS) $0   # second record in pair is appended to
}                                    # first ORS separated
END {
    n=asort(a,b,"@ind_str_asc")      # sort on key
    for(i=1;i<=n;i++)                # loop them
        print b[i]                   # and output
}' file
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8

它仅支持$2 中的唯一键。组记录具有相同的$2但在该组内没有排序,例如:

$ awk '{...}' file file
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8

答案 2 :(得分:1)

与@Charles的答案类似,但使用小db.mycollection.insertOne({name:"Joseph", age: 18}) 脚本而不是bash函数。

将以下内容保存在自己的文件中,名为(例如)sortem.sh:

awk

通过以下方式使文件可执行:

#!/usr/bin/env bash

set -e

[[ $# -ge 1 ]] && exec < "$1"

awk -F , '/^#EXTINF/ {s=$0} /^http/ {print s FS $0}' | \
  sort -t , -k 2,2 | \
  awk -F , '{print $1 FS $2 "\n" $3}'

标识要保存输入的文件。例如,您可以将其保存在名为$ chmod +x sortem.sh 的文件中。使用sortem_input.txt显示此文件的内容显示:

cat

使用如下调用处理此输入:

$ cat sortem_input.txt
#EXTINF:-1 group-title="SERVER 1-Tv" tvg-logo="http://anotherRandomUrl.com/icon.png",NBC
http://AnotherStreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://randomUrl.com/icon.png",ABC HD
http://StreamUrl.m3u8
#EXTINF:-1 tvg-logo="http://YetAnotherRandomUrl.com/icon.png",Discovery
http://DisStreamUrl.m3u8

...或:

$ ./sortem.sh sortem_input.txt

...或更一般地说:

$ ./sortem.sh < sortem_input.txt 

输出如下:

$ <commands that generate input> | ./sortem.sh