Dar*_*ner 6 bash awk text-processing regular-expression
我有一个变量 ,var
其中包含:
XXXX YY ZZZZZ\n
aaa,bbb,ccc
Run Code Online (Sandbox Code Playgroud)
我想要的只是aaa
第二行。我试过:
out=$(echo "$var" | awk 'NR==2{sub(",.*","")}' )
Run Code Online (Sandbox Code Playgroud)
但我没有得到任何输出。我尝试使用,
as FS 但我无法得到正确的语法。我真的很想学习 awk/regex 语法。
我想在其他地方使用 out 作为变量“$out”——而不是打印。
ter*_*don 17
你不想要正则表达式。整个要点awk
是自动将一行拆分为多个字段,因此只需将字段分隔符设置为,
并打印第二行的第一个字段:
$ printf '%s' "$var" | awk -F, 'NR==2{print $1}'
aaa
Run Code Online (Sandbox Code Playgroud)
或者,如果您的 shell 支持<<<
:
$ awk -F, 'NR==2{print $1}' <<<"$var"
aaa
Run Code Online (Sandbox Code Playgroud)
如果您确实想手动执行而不awk
按预期使用,您可以执行以下操作:
$ awk 'NR==2{sub(/,.*/,""); print}' <<<"$var"
aaa
Run Code Online (Sandbox Code Playgroud)
您没有得到任何输出,因为您没有告诉awk
打印任何内容。
或者,您也可以在此处使用${param#pattern}
和${param%%pattern}
标准参数扩展运算符:
NL='\n'\nout=${var#*"$NL"} # removes first line. Assumes there are at least 2\nout=${out%%"$NL"*} # removes all but the first line\nout=${out%%,*} # removes everything after the first ,\n
Run Code Online (Sandbox Code Playgroud)\n或者bash
具体而言,您可以使用:
LC_ALL=C # needed to accept non-text\n[[ $var =~ ^[^$'\\n']*$'\\n'([^,$'\\n']*) ]]\nout=${BASH_REMATCH[1]}\n
Run Code Online (Sandbox Code Playgroud)\n标准情况下,还有expr
:
NL='\n'\nout=$(LC_ALL=C expr "x$var" : "[^$NL]*$NL\\([^,$NL]*\\)")\n
Run Code Online (Sandbox Code Playgroud)\n您的方法的问题是您没有告诉awk
打印任何内容。如果awk
不打印任何内容,则变量中不会存储任何内容,因为$(...)
它会扩展为 \xc2\xb9 内命令的输出。另外,请记住echo
不能用于打印任意数据。
out=$(printf '%s\\n' "$var" | awk 'NR == 2 {sub(",.*", ""); print}')\n
Run Code Online (Sandbox Code Playgroud)\n或者:
\nout=$(printf '%s\\n' "$var" | awk -F, 'NR == 2 {print $1}')\n
Run Code Online (Sandbox Code Playgroud)\n\xc2\xb9 减去尾随换行符,如果输出包含 NUL 字节,则 shell 实现之间的行为会有所不同
\n另一种选择使用sed
:
sed -n 's/,.*$//p' <<< "$var"
Run Code Online (Sandbox Code Playgroud)
s/../../
) 从每,
行的第一个 开始到行尾 ( ) 的所有内容替换为“无”,从而仅保留第一个之前的,.*$
部分。,
-n
选项,默认情况下会抑制输出。p
程序末尾的 指示仍然sed
打印找到“搜索”模式的行。这样,我们忽略第一行(不带),只处理实际找到,
a 的第二行。,
像往常一样,您可以通过命令替换将结果导入到 shell 变量中:
sed -n 's/,.*$//p' <<< "$var"
Run Code Online (Sandbox Code Playgroud)
或者,在不理解此处字符串的 shell 中,
out=$(sed -n 's/,.*$//p' <<< "$var")
Run Code Online (Sandbox Code Playgroud)
请注意,由于您没有包含边缘案例的示例,因此很难设计解决方案来容纳$var
. 当前的解决方案假设只有一行带有 a ,
,您要从中提取第一个字段。
awk -F, '/,/ {print $1}' <<< "$var"
Run Code Online (Sandbox Code Playgroud)
这告诉我们awk
使用逗号字符作为字段分隔符,并搜索包含逗号的任何行。一旦找到包含逗号的行,awk 就会被告知打印该行的第一个字段,即直到第一个逗号但不包括第一个逗号的所有内容。