Linux 如何从文本文件中为grep信息编写sed脚本
我正在尝试做我的家庭作业,仅限于使用Linux 如何从文本文件中为grep信息编写sed脚本,linux,sed,append,newline,Linux,Sed,Append,Newline,我正在尝试做我的家庭作业,仅限于使用sed将输入文件过滤为特定格式的输出。这是输入文件(名为stocks): 输出需要是: BAC, CSCO, INTC, MSFT, VZ, KO, MMM 我确实想出了一个解决办法,但效率不高。这是我的sed脚本(名为try.sed): 我在shell上运行的命令是: $ sed -nf try.sed stocks 我的问题是,有没有更好的方法使用sed来获得相同的结果?我编写的脚本只能处理7行数据。如果数据较长,我需要重新修改脚本。我不知道怎样才能让
sed
将输入文件过滤为特定格式的输出。这是输入文件(名为stocks
):
输出需要是:
BAC, CSCO, INTC, MSFT, VZ, KO, MMM
我确实想出了一个解决办法,但效率不高。这是我的sed
脚本(名为try.sed
):
我在shell上运行的命令是:
$ sed -nf try.sed stocks
我的问题是,有没有更好的方法使用sed来获得相同的结果?我编写的脚本只能处理7行数据。如果数据较长,我需要重新修改脚本。我不知道怎样才能让它变得更好,所以我来这里寻求帮助
感谢您的建议。此sed命令应生成您所需的输出:
sed -rn '/[0-9]+$/{s/^([^;]*).*$/\1/p;}' file.txt
或在Mac上:
sed -En '/[0-9]+$/{s/^([^;]*).*$/\1/p;}' file.txt
<> > >编辑:我编辑了我的算法,因为我忽略了页眉和页脚(我认为它们只是为了我们的利益)。 sed根据其设计,访问输入文件的每一行,然后对符合某些规范(或无)的行执行表达式。如果你把你的脚本裁剪成一定数量的行,你肯定是做错了什么!我不会给你写剧本,因为这是家庭作业,但一种方法的总体思路是写一个剧本,完成以下任务。将排序视为脚本中事物的顺序
d
跳过前三行,这将删除图案空间并立即移动到下一行s
(substitute)命令将第一个分号(;
)后面的所有内容替换为逗号和空格(“,”)H
)sed
通常提供不同复杂度的不同方法来完成任务。我用这种方法编写的解决方案有10行长
请注意,我不需要抑制打印(使用-n
)或手动打印(使用p
);默认情况下打印每一行。我的脚本如下所示:
$ sed -f companies.sed companies
BAC, CSCO, INTC, MSFT, VZ, KO, MMM
使用
sed
的另一种方法:
/.*;.*;[0-9].*/ { N
N
N
N
N
N
s/\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*\n\(.*\);.*;.*/\1, \2, \3, \4, \5, \6, \7/gp
}
sed -ne '/^====/,/^====/ { /;/ { s/;.*$// ; H } }; $ { g ; s/\n// ; s/\n/, /g ; p }' stocks
输出:
BAC, CSCO, INTC, MSFT, VZ, KO, MMM
说明:
-ne # Process each input line without printing and execute next commands...
/^====/,/^====/ # For all lines between these...
{
/;/ # If line has a semicolon...
{
s/;.*$// # Remove characters from first semicolon until end of line.
H # Append content to 'hold space'.
}
};
$ # In last input line...
{
g # Copy content of 'hold space' to 'pattern space' to work with it.
s/\n// # Remove first newline character.
s/\n/, /g # substitute the rest with output separator, comma in this case.
p # Print to output.
这可能适合您:
sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stocks
- 我们不需要标题,所以让我们删除它们<代码>1d
- 所有数据项由
分隔代码>,让我们把注意力集中在这些行上<代码>//代码>
- 以上内容中,删除第一个
中的所有内容代码>到行的末尾,然后将其塞进保留空间(HS)
{s/;*/;H}
- 当到达最后一行时,使用
命令用HS覆盖它,删除第一个换行符(由g
命令生成),用逗号和空格替换所有后续换行符,并打印出剩余的换行符<代码>${g;s/;s/\n/,/g;q}H
- 删除所有其他内容
d
cat <<! >stock # paste the file into a here doc and pass it on to a file
> Symbol;Name;Volume
> ================================================
>
> BAC;Bank of America Corporation Com;238,059,612
> CSCO;Cisco Systems, Inc.;28,159,455
> INTC;Intel Corporation;22,501,784
> MSFT;Microsoft Corporation;23,363,118
> VZ;Verizon Communications Inc. Com;5,744,385
> KO;Coca-Cola Company (The) Common;3,752,569
> MMM;3M Company Common Stock;1,660,453
>
> ================================================
> !
sed '1d;/;/!d' stock # delete headings and everything but data lines
BAC;Bank of America Corporation Com;238,059,612
CSCO;Cisco Systems, Inc.;28,159,455
INTC;Intel Corporation;22,501,784
MSFT;Microsoft Corporation;23,363,118
VZ;Verizon Communications Inc. Com;5,744,385
KO;Coca-Cola Company (The) Common;3,752,569
MMM;3M Company Common Stock;1,660,453
sed '1d;/;/{s/;.*//p};d' stock # delete all non essential data
BAC
CSCO
INTC
MSFT
VZ
KO
MMM
sed '1d;/;/{s/;.*//;H};${g;l};d' stock # use the l command to see what's really there!
\nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;l};d' stock # refine refine
BAC, CSCO, INTC, MSFT, VZ, KO, MMM$
sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stock # all done!
BAC, CSCO, INTC, MSFT, VZ, KO, MMM
cat符号;名称卷
> ================================================
>
>美国银行;美国银行股份有限公司;238,059,612
>CSCO;思科系统公司。;28,159,455
>INTC;英特尔公司;22,501,784
>MSFT;微软公司;23,363,118
>VZ;威瑞森通讯公司,;5,744,385
>高,;可口可乐公司(通用);3,752,569
>嗯,;3M公司普通股;1,660,453
>
> ================================================
> !
sed'1d;/;/!d'stock#删除标题和除数据行以外的所有内容
美国银行;美国银行股份有限公司;238,059,612
CSCO;思科系统公司。;28,159,455
INTC;英特尔公司;22,501,784
MSFT;微软公司;23,363,118
VZ;威瑞森通讯公司,;5,744,385
让开;可口可乐公司(通用);3,752,569
嗯,;3M公司普通股;1,660,453
sed'1d;//{s/;*//p};d'库存#删除所有非必要数据
美国银行
CSCO
INTC
MSFT
VZ
击倒对手
嗯
sed'1d;//{s/;*/;H}${g;l};d'stock#使用l命令查看实际情况!
\nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
sed'1d;//{s/;*/;H}${g;s//;s/\n/,/g;l};d’库存#精炼
BAC、CSCO、INTC、MSFT、VZ、KO、MMM$
sed'1d;//{s/;*/;H}${g;s//;s/\n/,/g;q};d’stock,全部完成!
BAC、CSCO、INTC、MSFT、VZ、KO、MMM
亲爱的anubhava,我已经运行了您的命令,但输出不在一行中。挑战之一是将所有换行符替换为逗号和1个空格(最后一行除外)。最后一个后面不应该有逗号。是的,我的脚本的行为与grep-o完全一样,因为现在我意识到这是一个家庭作业,我将把脚本的其余部分留给你。@Jayce关于你答案的另一个提示是使用标签(如@Dan在他的答案中所建议的),使用N
并用替换换行符
,
和空间
谢谢Jaypal和Anubhava。。。我试图阅读更多关于b和t命令标签的内容。虽然,我还不太明白t在做什么……+1承认这是家庭作业,并承认这是疯狂的s/\(.*)/代码>你放进去的东西!祝你好运。@Jayce上面哪一部分你有问题?如果可以的话,我想改进我的解释!嗨,丹,谢谢你的提示。1秒
cat <<! >stock # paste the file into a here doc and pass it on to a file
> Symbol;Name;Volume
> ================================================
>
> BAC;Bank of America Corporation Com;238,059,612
> CSCO;Cisco Systems, Inc.;28,159,455
> INTC;Intel Corporation;22,501,784
> MSFT;Microsoft Corporation;23,363,118
> VZ;Verizon Communications Inc. Com;5,744,385
> KO;Coca-Cola Company (The) Common;3,752,569
> MMM;3M Company Common Stock;1,660,453
>
> ================================================
> !
sed '1d;/;/!d' stock # delete headings and everything but data lines
BAC;Bank of America Corporation Com;238,059,612
CSCO;Cisco Systems, Inc.;28,159,455
INTC;Intel Corporation;22,501,784
MSFT;Microsoft Corporation;23,363,118
VZ;Verizon Communications Inc. Com;5,744,385
KO;Coca-Cola Company (The) Common;3,752,569
MMM;3M Company Common Stock;1,660,453
sed '1d;/;/{s/;.*//p};d' stock # delete all non essential data
BAC
CSCO
INTC
MSFT
VZ
KO
MMM
sed '1d;/;/{s/;.*//;H};${g;l};d' stock # use the l command to see what's really there!
\nBAC\nCSCO\nINTC\nMSFT\nVZ\nKO\nMMM$
sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;l};d' stock # refine refine
BAC, CSCO, INTC, MSFT, VZ, KO, MMM$
sed '1d;/;/{s/;.*//;H};${g;s/.//;s/\n/, /g;q};d' stock # all done!
BAC, CSCO, INTC, MSFT, VZ, KO, MMM