使用 awk 删除“,”后面的所有内容

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打印任何内容。


Sté*_*las 8

或者,您也可以在此处使用${param#pattern}${param%%pattern}标准参数扩展运算符:

\n
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具体而言,您可以使用:

\n
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

\n
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不能用于打印任意数据。

\n
out=$(printf '%s\\n' "$var" | awk 'NR == 2 {sub(",.*", ""); print}')\n
Run Code Online (Sandbox Code Playgroud)\n

或者:

\n
out=$(printf '%s\\n' "$var" | awk -F, 'NR == 2 {print $1}')\n
Run Code Online (Sandbox Code Playgroud)\n
\n

\xc2\xb9 减去尾随换行符,如果输出包含 NUL 字节,则 shell 实现之间的行为会有所不同

\n


Adm*_*Bee 7

另一种选择使用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 ,,您要从中提取第一个字段。


Jim*_* L. 6

awk -F, '/,/ {print $1}' <<< "$var"
Run Code Online (Sandbox Code Playgroud)

这告诉我们awk使用逗号字符作为字段分隔符,并搜索包含逗号的任何行。一旦找到包含逗号的行,awk 就会被告知打印该行的第一个字段,即直到第一个逗号但不包括第一个逗号的所有内容。