我有以下用例:
echo "some comment char '\;' embedded in strings ; along with inline comments" \
| cut -d';' -f 1
我想:
some comment char ';' embedded in strings
我得到:
some comment char '
如何隐藏配置为剪切剪切的分隔符,如本用例所示?理想情况下, cut 会读取并尊重反斜杠,但如果不是这样,还有其他方法吗?
答案1
在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ echo "some comment char '\;' embedded in strings ; along with inline comments" |
awk -F';' '{gsub(/\\\\/,RS); gsub(/\\;/,"\\\\"); gsub(/\\\\/,";",$1); gsub(RS,"\\",$1); print $1}'
some comment char ';' embedded in strings
$ cat file
foo\;bar;baz
foo\\;bar;baz
$ awk -F';' '{gsub(/\\\\/,RS); gsub(/\\;/,"\\\\"); gsub(/\\\\/,";",$1); gsub(RS,"\\",$1); print $1}' file
foo;bar
foo\
并将其扩展为包含更多字段的行:
$ cat file
foo\;bar;baz
foo\\;bar;baz
foo\\;bar\;this\;that\\;baz;here\;and\;there
我们可以根据需要打印任何或所有字段(这里还首先输出原始行,并在包含单个字段的每个输出行的开头输出字段编号):
$ awk -F';' '{print; gsub(/\\\\/,RS) gsub(/\\;/,"\\\\"); for (i=1; i<=NF; i++) { gsub(/\\\\/,";",$i); gsub(RS,"\\",$i); print " " i, $i }; print "---" }' file
foo\;bar;baz
1 foo;bar
2 baz
---
foo\\;bar;baz
1 foo\
2 bar
3 baz
---
foo\\;bar\;this\;that\\;baz;here\;and\;there
1 foo\
2 bar;this;that\
3 baz
4 here;and;there
以上:
\\
将当前输入行 ( ) 中的每个字符转换$0
为换行符( 的默认值RS
),换行符是一个不能存在于换行符分隔记录中的字符串,因此我们可以\\;
在输入中将其处理为转义的反斜杠而不是转义的半字符冒号,那么- 将每个
\;
in转换$0
为\\
,它现在也是一个不能存在于 $0 中的字符串,因为我们只是将它们全部转换为RS
s,以摆脱;
其中的麻烦,然后 - 修改操作
$0
会导致 awk$0
在每个剩余的字段中重新拆分为字段;
,从而将我们所需的目标字符串放入 中$1
,然后 - 我们将 every
\\
(在上面第 2 步创建的)转换$1
为;
,然后 - 将 every
RS
(在上面的步骤 1 创建的)转换$1
回\\
,然后 - 我们打印该字段,
$1
该方法适用于RS
POSIX 定义的每个文字字符串,如果您RS
是某些 awks 支持的正则表达式,例如 GNU awk,则提出一个不带正则表达式元字符的字符串,该字符串与该正则表达式匹配以用作替换的RS
答案2
使用 GNUgrep
或兼容的(对于非标准但现在相当常见的-o
选项):
grep -Eo '^(\\.|[^\\;])*'
它匹配并输出 0 个或多个 ( )1o
的序列,后跟任何单个字符 ( ),该字符涵盖转义但也转义或除和以外的任何字符,位于行的开头 ( )。*
\
.
;
\
\
;
^
例子:
$ cat file
foo\;bar;baz
foo\\;bar;baz
$ grep -Eo '^(\\.|[^\\;])*' file
foo\;bar
foo\\
要删除转义,请通过管道传输到,或者如果您也支持该选项sed 's/\\\(.\)/\1/g'
,则执行整个操作:sed
sed
-E
$ sed -E 's/^((\\.|[^\\;])*).*/\1/; s/\\(.)/\1/g' file
foo;bar
foo\
或者与perl
:
$ perl -lpe 's/^(\\.|[^;])*+\K.*//; s/\\(.)/$1/g' file
foo;bar
foo\
1 但请注意,grep -o
不会输出空匹配项。