Unix 如何使用Shell脚本交换文件中与条件匹配的行

Unix 如何使用Shell脚本交换文件中与条件匹配的行,unix,match,conditional-statements,swap,lines,Unix,Match,Conditional Statements,Swap,Lines,我有一个文件,其中每行的第28个字符是“a”或“D”。 我希望以这样的方式交换行,即文件的第一行应该有第28个字符“D”和 文件的第二行应该有28个字符作为“A”。 这个模式应该一直延续到整个文件 输入文件: 00254920141228N201412251850A201412241740SA1118WE1440SCL 00254920141228N201412251850D201412200050SA1150TH1850000 00254920141228R201412251850A20141

我有一个文件,其中每行的第28个字符是“a”或“D”。 我希望以这样的方式交换行,即文件的第一行应该有第28个字符“D”和 文件的第二行应该有28个字符作为“A”。 这个模式应该一直延续到整个文件

输入文件:

00254920141228N201412251850A201412241740SA1118WE1440SCL
00254920141228N201412251850D201412200050SA1150TH1850000
00254920141228R201412251850A201412241740SA1118WE1440SCL
00254920141228R201412251850A201412241740SA1118WE1440SCL
00254920141228R201412251850D201412200050SA1150TH1850000
00254920141228R201412251850D201412200050SA1150TH1850000
输出应为:

00254920141228N201412251850D201412200050SA1150TH1850000
00254920141228N201412251850A201412241740SA1118WE1440SCL
00254920141228R201412251850D201412200050SA1150TH1850000
00254920141228R201412251850A201412241740SA1118WE1440SCL
00254920141228R201412251850D201412200050SA1150TH1850000
00254920141228R201412251850A201412241740SA1118WE1440SCL

我希望脚本用Unix shell脚本编写。

这里是一个简单的Python脚本,它实现了我认为您试图描述的内容

from sys import stdin
keep = "A"
kept = []
for line in stdin:
    line = line.rstrip("\r\n")
    pattern = line[27:28]
    # print("## keep %s, pattern %s, %s" % (keep, pattern, line))
    if pattern != keep:
        if len(kept) > 0:
            print line
            # print("### len kept == %i, popping" % len(kept))
            print kept.pop(0)
        else:
            # print("### no kept, just print")
            print line
            keep = pattern
    else:
        # print("### keeping for later")
        keep = pattern
        kept.append(line)
if len(kept) > 1:
    raise ValueError("Too many %s lines" % keep)
elif len(kept) == 1:
    print kept[0]
我留下了调试打印,希望您能看到正在发生的事情——在打印语句中取消注释
#
,以获得一些调试诊断,如果它不能完全满足您的需要

实际上,为了简单起见,我开始将其作为一个Awk脚本来编写,但是Awk数组没有push/pop,所以它变得比我喜欢的更复杂

我不会为此使用
sed
。我不怀疑这是可行的,但它将很难保持,特别是如果你和你的所有同事都承诺保持高度流利的
sed
。(这是说“只写语言”的更好方式…)

我一直对所有Python字符串使用双引号。这样,您就可以将其嵌入一个简单的shell脚本中进行测试,如下所示:

#!/bin/sh
python -c '... text
of
script' <<':'
sample
data
:
#/垃圾箱/垃圾箱
python-c'。。。文本
属于

脚本“你尝试了什么,怎么失败的?”?为什么你的样本数据有错误,但你的问题Ä?样本数据是正确的。第28行的每一个字符都是A或D。我已经用SED写了一个逻辑,但它不起作用。你能提供进一步的建议吗?发布你的
sed
脚本(包括它的问题)并解释它有什么问题。关于详细的发布指南,请参阅这一节。我最初写这篇文章是为了尽可能保持输入的顺序,然后只有在输入出现错误时才触发;将第一个赋值更改为
keep=None
,以恢复此行为。您的问题特别要求第一行包含D,即在文件开头保留任何A行,以备以后使用。感谢您的脚本。我是Python新手,但我将能够在solaris环境中运行Python脚本。我需要将输入文件作为参数吗?我有太多类似于示例数据的行,当我执行完整文件时,它抛出以下错误0为了解决编辑错误,我在代码中给出了SHIFT+TAB,然后错误消失了,但现在我面临一个新的错误回溯(最近一次调用):文件“”,第23行,in-ValueError:A行太多。如果存在未使用的保留行队列,且在输入结束时从未与D行配对,则脚本不知道该怎么办。在这种情况下,我将其编码为投诉。如果您可以指定应该发生什么,我可以更新它。