请考虑这个片段:
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
类似的复杂情况?
答案1
or将从末尾删除换行符,但要以编程方式执行此操作,请``
使用.$()
tr
grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\012\015'
这将从字符串中删除回车符和/或换行符。
问题可能在于你如何输出结果。例如,默认情况下echo
添加换行符。您可能想使用echo -n
或printf
。
答案2
这似乎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 方式评估数据,因此这只会打印第一个匹配项。
答案3
我更喜欢这种方式
grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\n'
答案4
grep 的普通版本(包括 grep -P)总是输出一个与其匹配的换行符,因此如果您只有一个结果(或者您只想删除最后添加的换行符),则只需删除最后一个字符就足够了的输出,您可以通过管道将其通过 来完成head -c-1
。