AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-133219

Ed Morton's questions

Martin Hope
Ed Morton
Asked: 2024-12-07 21:13:12 +0800 CST

为什么 grep/sed/awk 中 ' 的 ASCII 转义序列处理方式不同?

  • 13

使用所有 3 个工具的 GNU 版本(向下滚动查看 FreeBSD 尝试),如果我想'使用带有'-delimited 脚本的 awk 在输入中查找,我们可以尝试使用十六进制和八进制转义序列进行匹配:

$ echo "'" | awk '/\x27/'
'

$ echo "'" | awk '/\047/'
'

$ echo "'" | awk '/\o047/'
awk: cmd. line:1: warning: regexp escape sequence `\o' is not a known regexp operator

因此,正如您直观预期的那样,前两个方法有效,而第三个方法无效。

现在让我们用 sed 尝试同样的操作(带或不带-E):

$ echo "'" | sed -n '/\x27/p'
'

$ echo "'" | sed -n '/\047/p'
$

$ echo "'" | sed -n '/\o047/p'
'

和 grep (带或不带-E):

$ echo "'" | grep '\x27'
grep: warning: stray \ before x

$ echo "'" | grep '\047'
grep: warning: stray \ before 0

$ echo "'" | grep '\o047'
grep: warning: stray \ before o

所以:

  1. 最重要的是:它们为什么不同?
  2. 第二个好奇心:有没有办法在 grep 中使用转义序列进行匹配,'而无需诉诸 GNU greps 不可移植-P选项,也不需要在 grep 使用诸如这样的 shell 构造看到转义序列之前扩展转义序列grep $'\047'?

值得注意的是,八进制\047是 awk 中推荐的转义序列(请参阅http://awk.freeshell.org/PrintASingleQuote或https://web.archive.org/web/20230530010453/http://awk.freeshell.org/PrintASingleQuote,如果发生故障)。

就这个问题而言,我对允许文字的替代方案'或其他任何工具的功能或其他任何事情都不感兴趣,我只是想找出为什么这 3 个特定的正则表达式匹配工具对 ASCII 转义序列的处理方式彼此不同。但是,我有兴趣了解 BSD 或这 3 个工具的其他变体在给定上述相同脚本的情况下如何表现。

附加信息:

FreeBSD

这是 FreeBSD 13.1 的行为:

% echo "'" | awk '/\x27/'
'
% echo "'" | awk '/\047/'
'
% echo "'" | sed -n '/\x27/p'
'
% echo "'" | sed -n '/\047/p'
% echo "'" | sed -n '/\o047/p'
sed: 1: "/\o047/p": RE error: trailing backslash (\)
% echo "'" | grep '\x27'
grep: trailing backslash (\)
% echo "'" | grep '\047'
% 

POSIX

以下是正则表达式的 POSIX 标准和相关 3 个工具对此的说明:

  • 正则表达式:https ://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html
  • awk: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/awk.html
  • sed: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/sed.html
  • grep: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/grep.html

从正则表达式规范中我们看到,BRE或EREx中都不0是“特殊字符”,因此它们是“普通字符”,并且

当不在括号表达式中时,未转义字符前面的普通字符的解释是未定义的,但以下情况除外:

后面跟着字符列表,其中不包含0BRE或ERE ,因此我的结论是,在 POSIX 的正则表达式中,既没有定义行为,也没有定义x行为。\x27\047

POSIX awk 规范正则表达式部分说明:

\ddd
一个字符后跟一个、两个或三个八进制数字的最长序列 (01234567)。如果所有数字均为 0(即 NUL 字符的表示),则行为未定义。如果数字产生的值大于八进制 377,则行为未定义。

所以我们知道\0是为 POSIX awk 定义的但\x事实并非如此,所以 awk 的行为\x未由 POSIX 为 awk 定义,因此留给各种 awk 实现。

POSIX sed 规范正则表达式部分为正则表达式添加了一些变化,但没有提及\0或\x并且遵循 POSIX 正则表达式定义,因此POSIX 对于 sed 未定义\0或。\x

POSIX grep 规范描述部分完全遵循 POSIX 正则表达式定义,因此\0POSIX\x对 grep 未定义。

因此显然 的含义\xdd取决于 grep、sed 和 awk 的工具实现者,而 的含义\0dd是为 awk 定义的,但取决于 grep 和 sed 的实现者。

GNU 手册

GNU awk 手册转义序列部分说明:

\nnn
八进制值 nnn,其中 nnn 代表“0”和“7”之间的 1 到 3 位数字。例如,ASCII ESC(转义)字符的代码为“\033”。

\xhh…
十六进制值 hh,其中 hh 代表十六进制数字序列('0'–'9',以及 'A'–'F' 或 'a'–'f')。'\x' 后最多允许两位数字...

这就是\x47GNU awk 的定义。

GNU sed 手册转义序列部分说明:

\oxxx
生成或匹配八进制 ASCII 值为 xxx 的字符。

\xxx
生成或匹配十六进制 ASCII 值为 xx 的字符。

\o047这就是\x27GNU sed 的定义。

GNU grep 手册中没有我找到的对十六进制或八进制转义序列的引用,这解释了我们在尝试使用它们时看到的警告消息,大概意味着它们在 GNU grep 中不受支持。

awk
  • 1 个回答
  • 423 Views
Martin Hope
Ed Morton
Asked: 2024-07-21 20:32:52 +0800 CST

我怎样才能让 tput 填充整个背景而不留边框?

  • 7

我在 Windows 笔记本电脑上的 cygwin 中使用 bash。我希望能够将终端的背景颜色更改为绿色(实际颜色无关),为此我可以使用以下任一命令:

  1. tput setb 2; echo
  2. printf '\e]11;#00FF00\a'

有关其printf功能的更多信息,请参阅如何设置 Linux 控制台屏幕的背景颜色,背景的具体用法11记录在https://invisible-island.net/xterm/ctlseqs/ctlseqs.pdf(Ps = 1 0 → Change VT100 text foreground color to Pt.和Ps = 1 1 → Change VT100 text background color to Pt.)的第 34 页中。

立即printf更改整个终端的背景,而tput仅设置接下来输入的颜色,因此echo从下一个空行开始,但我不太关心这些。我最关心的是以下内容:

留下tput了原始背景颜色的小边框(浅米色,通过单击终端左上角的“选项”GUI 设置),如下图所示(图像左下角周围的浅灰色是我的 Windows 桌面颜色):

在此处输入图片描述

改变printf边框的颜色(与 相比,它是较浅的绿色,tput但这并不重要):

在此处输入图片描述

但它不会改变设置的背景区域,tput除非我首先重新初始化原来的操作tput,tput init; echo然后执行printf:

在此处输入图片描述

printf只要我不先使用,我就可以使用它来获得我想要的东西tput setb,但我更愿意只在可以移植的情况下使用tput setb,那么 - 为什么要tput留下现有背景颜色的小边框,有什么方法可以告诉tput以不留下小边框的方式设置背景颜色?

我还想知道是否有办法tput立即设置整个终端背景,printf而不是在我输入下一个字符串之后,但这并不像摆脱边框那么重要。

现在@MarcusMüller在评论中向我暗示这可能是一个mintty问题 -

git bash当我在另一台机器上使用 Windows 时,我看到了同样的行为。它们显然都用作mintty终端仿真器。由于我必须登录到许多不同的 Windows 机器并使用cygwin或git bash,我希望能够解决这个问题,而不必每次使用其中一台机器时都更改终端仿真器(我甚至不确定是否/如何做到这一点)。事实上,如果要通过更改终端仿真器来解决问题tput,我只会使用这种printf方法。

我在set-border-width-for-mintty-window-on-cygwin-windows-10中找到了一种方法,通过~/.minttyrc设置Padding变量来控制边框宽度,如果我将其更新为:

Padding=0

那么这确实可以解决上述tput问题,但是

  1. 这意味着我必须.minttyrc在每台登录的机器上更改,然后重新启动终端,并且
  2. 当我打开“选项”GUI 来更改有关终端的任何内容然后保存时,它会覆盖该.minttyrc文件并删除Padding设置

所以我仍然想找到某种方法来简单地告诉tput填充该“填充”区域,就像填充背景的其余部分一样。

@Vilinkameni还在评论中指出,tput在 a minttyandMSYS2 MINGW64终端中使用上述命令时,任何ls --color使用颜色的后续命令或其他命令进行的 ANSI SGR 颜色切换都会有效地再次重置颜色。如果我使用上述命令,则不会发生这种情况,printf因此我可能会在后续问题中询问。

另请参阅底部的“更改颜色” https://code.google.com/archive/p/mintty/wikis/Tips.wiki#Changing_colours,了解有关上述内容printf和其他相关内容的更多信息mintty。我的$TERM值是xterm。

terminal
  • 1 个回答
  • 63 Views
Martin Hope
Ed Morton
Asked: 2023-07-04 01:39:25 +0800 CST

“head”读取/消耗的输入行数可以多于其输出的行数吗?

  • 18

给定以下 3 个脚本:

  1. printf 'a\nb\nc\n' > file && { head -n 1; cat; } < file
  2. printf 'a\nb\nc\n' | { head -n 1; cat; }
  3. { head -n 1; cat; } < <(printf 'a\nb\nc\n')

我期望每个的输出是:

a
b
c

但对于其中一些系统,在某些系统上,情况并非如此。例如,在 cygwin 上:

$ printf 'a\nb\nc\n' > file && { head -n 1; cat; } < file
a
b
c

$ printf 'a\nb\nc\n' | { head -n 1; cat; }
a

$ { head -n 1; cat; } < <(printf 'a\nb\nc\n')
a

是什么导致这些脚本的输出不同?


附加信息 - 这显然不仅仅是一个head问题:

$ printf 'a\nb\nc\n' | { sed '1q'; cat; }
a
$ printf 'a\nb\nc\n' | { awk '1;{exit}'; cat; }
a

$ { sed '1q'; cat; } < <(printf 'a\nb\nc\n')
a
$ { awk '1;{exit}'; cat; } < <(printf 'a\nb\nc\n')
a

shell 中的一种健壮的 POSIX 方式(即不只是调用 awk 或类似的一次来完成所有操作)从输入中读取一些行并将其余行留给不同的命令,无论输入是否来自管道或一份文件?


这个问题的灵感来自于根据某个列中的值对整个 .csv 进行排序的答案下的评论。

bash
  • 1 个回答
  • 724 Views
Martin Hope
Ed Morton
Asked: 2022-07-03 04:41:25 +0800 CST

什么控制 bash 中的“无效间接扩展”报告?

  • 1

当变量未设置时,我一直在使用间接扩展并依赖结果为空字符串:

$ $SHELL --version | head -1
GNU bash, version 4.4.23(1)-release (x86_64-unknown-linux-gnu)
$ unset var
$ echo "${!var}"

$

但是在一个失败的新Linux机器上invalid indirect expansion:

$ $SHELL --version | head -1
GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu)
$ unset var
$ echo "${!var}"
-bash: var: invalid indirect expansion
$

显然,我可以更改我的代码以在两个地方都工作,但到目前为止,我还无法弄清楚导致 1 失败但另一个失败的 2 个系统之间的确切区别,我想知道这种区别是什么最好解决这个问题以及将来出现的任何类似问题。

如果只是 bash 版本的变化,我找不到任何发行说明或任何表明这一点的东西。如果在一个选项上设置了某个选项,我也找不到(set -u例如不是)。FWIW 这shopt是发生故障的机器(第二列)和未发生故障的机器(第三列)之间的输出差异:

$ awk 'FNR==1{ARGIND++} {a[$1,ARGIND]=$2; b[$1]} END{for (var in b) if (a[var,1] != a[var,2]) print var, a[var,1], a[var,2]}' bad good | column -t
autocd              off
compat32            off
localvar_unset      off
lastpipe            off
localvar_inherit    off
complete_fullquote  on
assoc_expand_once   off
checkwinsize        on   off
globasciiranges     on
compat40            off
compat41            off
compat42            off
inherit_errexit     off
compat43            off
compat44            off
checkjobs           off
expand_aliases      on   off
globstar            off
progcomp_alias      off
dirspell            off
direxpand           off
login_shell         on   off

任何人都确切地知道为什么我在一个 Unix 机器上看到失败,而在另一个机器上却没有?

bash
  • 1 个回答
  • 73 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve