使grep输出而不尾随换行符


8

请考虑以下代码段:

X=$(grep -m1 'some-pattern' some-file | sed -n 's/.* //p')

如果某个模式条件与任意文本文件中的行匹配,我想将最后一个单词放在变量中

我的问题是,变量最后X要有CR或LF或CRLF,具体取决于要删除的源文件,因为它干扰了我打算执行的后续操作。
我什至尝试过类似的方法:

X=$(grep -m1 'some-pattern' some-file | sed -n 's/.* \([A-Za-z]\+\)/\1/p')

因此,期望sed输出受到限制,[A-Za-z]+但X变量中仍然有此讨厌的字节。

我怎样才能摆脱它,而无需使用像看到的是什么字节在结束了太多的代码,xxd那么cut它和类似的并发症?

Answers:


4

看起来awk这是满足您需求的更好选择,因为这些问题不存在,因为它可以使用字段和记录:

x=$(awk '/some-pattern/ { sub(/\r$/, "") ; printf("%s", $NF) ; exit }' some-file)

替换避免了CRLF行尾的问题。

sub(/\r$/, "")删除尾随的CR(如果存在)。由于awk治疗\n的记录(行)分隔符,你不需要剥离它,因为它是不是在数据被注视。

printf("%s", $NF)打印$NF没有尾随换行符的最后一个字段()(默认情况下,print其他一些awk函数会附加换行符)。

exit发生在前两个动作之后-这等效m1于您的grep命令行。这样可以确保awk在执行前两个命令后退出-并且由于这些命令是在匹配时发出的,并且awk以FIFO方式评估数据,因此只会打印第一个匹配项。


谢谢,它看起来很优雅,但不幸的是CRLF仍在里面X
Zetah 2012年

:)现在,它看起来不再优雅,仍然
不怎么

@zetah-不会CR,但是会有一个LF。我很难理解您想要从问题中得到什么,希望我的编辑能够满足您的需求。
克里斯·

好的,这一次很好-如果该行满足某种模式条件,则在一行中输出最后一个单词-不知道,也许对我来说很清楚,因为我有这个问题,然后很难以非母语的英语来解释。无论如何,如果有人用grep/sed解决方案来解决这个问题awk(我不理解),我将再等一会,否则,我将使用它。谢谢
zetah 2012年

@zetah-我将添加一个解释,以便您一秒钟就能更好地理解它。
克里斯·

7

``$()将删除末尾的新行,但要做到这一点编程,使用tr

grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\012\015'

这将从字符串中删除回车符和/或换行符。

可能的问题是如何输出结果。例如,默认情况下,echo添加换行符。您可能要使用echo -nprintf


这也将删除可能在整个字符串中发生的回车,这可能是不希望的。
克里斯·

是的,虽然可以在单行中嵌入回车符,但这种情况极为罕见。这样做-m1将确保只有一行输出,这很可能会在最后使回车。
Arcege 2012年

tr...有趣,可同时用于LF和CRLF文件。我会\010\013出于某种原因考虑,并且也\f\r可以正常工作。关于结果:我实际上并没有将输出放入变量中,而是将其作为变量包含$()在match-模式grepsome pipe | grep -o " $(...) "。感谢您的评论
Zetah 2012年


2

这对我有用:

grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d "\n" | tr -d "\r"

0

为什么不简单地sed进行[\r\f]清理:

# using Bash's $'string' idiom (that decodes ANSI C escape sequences)
# cf. http://wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- X="$(grep -m1 'some-pattern' some-file | sed -n 's/.* //p')"
+ X="$(grep -m1 'some-pattern' some-file | sed -n -e $'s/[\r\f]*$//' -e 's/.* //p')"

您的第二种方法缺少最终的正则表达式来捕获尾随的CR \r

# sample code to remove trailing \r with sed
# cf. http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)/\1/p' | od -c
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)[[:space:]]*/\1/p' | od -c

# keeps trailing space after c
printf 'a b c \r' | sed -n 's/^.* \([[:alpha:] ]\{1,\}\)[[:space:]]*/\1/p' | od -b

0

普通版本的grep(包括grep -P)总是输出与之匹配的换行符,因此,如果只有一个结果(或者只希望删除最后添加的换行符),只需删除最后一个字符就足够了的输出,您可以通过管道将其输出head -c-1

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.