如何对行组进行排序

  • 本文关键字:排序 bash sorting
  • 更新时间 :
  • 英文 :


在下面的示例中,必须对 3 个元素进行排序:

  1. "[aaa]"和它下面的 4 行(总是 4 行)形成一个单元。
  2. "[kkk]"和它下面的 4 行(总是 4 行)形成一个单元。
  3. "[zz]"和它下面的 4 行(总是 4 行)形成一个单元。

只应按此模式排序的行组;在"[aaa]"之前和"[zzz]"的第 4 行之后的任何内容都必须保持不变。

从:

This sentence and everything above it should not be sorted.
[zzz]
some
random
text
here
[aaa]
bla
blo
blu
bli
[kkk]
1
44
2
88
And neither should this one and everything below it.

自:

This sentence and everything above it should not be sorted.
[aaa]
bla
blo
blu
bli
[kkk]
1
44
2
88
[zzz]
some
random
text
here
And neither should this one and everything below it.

也许不是最快的:)[1] 但我相信它会做你想做的事:

for line in $(grep -n '^[.*]$' sections.txt |
              sort -k2 -t: |
              cut -f1 -d:); do
  tail -n +$line sections.txt | head -n 5
done

这是一个更好的:

for pos in $(grep -b '^[.*]$' sections.txt |
             sort -k2 -t: |
             cut -f1 -d:); do
  tail -c +$((pos+1)) sections.txt | head -n 5
done

[1] 第一个在文件中的行数类似于 O(N^2),因为它必须一直读取到每个部分的部分。第二个可以立即寻找正确的字符位置,应该更接近 O(N log N)。

[2] 这让你明白你的话,每个部分总是正好有五行(标题加上后面的四行),因此head -n 5 .但是,如果有必要,将其替换为以"["开头但不包括下一行的内容非常容易。


保留开始和结束需要更多的工作:

# Find all the sections
mapfile indices < <(grep -b '^[.*]$' sections.txt)
# Output the prefix
head -c+${indices[0]%%:*} sections.txt
# Output sections, as above
for pos in $(printf %s "${indices[@]}" |
             sort -k2 -t: |
             cut -f1 -d:); do
  tail -c +$((pos+1)) sections.txt | head -n 5
done
# Output the suffix
tail -c+$((1+${indices[-1]%%:*})) sections.txt | tail -n+6

您可能希望从中创建一个函数或脚本文件,将部分.txt更改为 1 美元。

假设其他行不包含[

header=`grep -n 'This sentence and everything above it should not be sorted.' sortme.txt | cut -d: -f1`
footer=`grep -n 'And neither should this one and everything below it.' sortme.txt | cut -d: -f1`
head -n $header sortme.txt #print header
head -n $(( footer - 1 )) sortme.txt | tail -n +$(( header + 1 )) | tr 'n[' '[n' | sort | tr 'n[' '[n' | grep -v '^[$' #sort lines between header & footer
#cat sortme.txt | head -n $(( footer - 1 )) | tail -n +$(( header + 1 )) | tr 'n[' '[n' | sort | tr 'n[' '[n' | grep -v '^[$' #sort lines between header & footer
tail -n +$footer sortme.txt #print footer

达到目的。

请注意,主要排序工作仅由第 4 个命令完成。其他行是保留页眉和页脚。

我还假设,在标题和第一个"[部分]"之间没有其他行。

这可能

对你有用(GNU sed & sort):

sed -i.bak '/^[/!b;N;N;N;N;s/n/UnIqUeStRiNg/g;w sort_file' file
sort -o sort_file sort_file
sed -i -e '/^[/!b;R sort_file' -e 'd' file
sed -i 's/UnIqUeStRiNg/n/g' file

排序后的文件将在file中,原始文件将在file.bak中。

这将按排序顺序显示以 [ 开头和之后 4 行的所有行。

UnIqUeStRiNg可以是不包含换行符的任何唯一字符串,例如 x00

相关内容

  • 没有找到相关文章

最新更新