从 AWK 中匹配的字符串模式中删除 \r\ 字符
Remove \r\ character from String pattern matched in AWK
我是 AWK 的新手,所以对于这个基本问题深表歉意。我找到了许多关于从文件中删除 windows 结束行字符但 none 匹配正则表达式并随后删除 windows 结束行字符的参考资料。
我有一个名为 infile.txt 的文件,其中包含如下一行:
...
DATAFILE data5v.dat
...
在 shell 脚本中,我想从此 infile.txt 捕获文件名参数 data5v.dat
并删除任何回车 return 字符,\r,如果存在。回车 return 可能并不总是存在。所以我必须匹配一个词,然后删除 \r 随后。
我尝试了以下方法,但没有达到我的预期效果:
FILENAME=$(awk '/DATAFILE/ { print gsub("\r", "", ) }' $INFILE)
我可以将匹配正则表达式 /DATAFILE/
的字符串 return 存储在我的 AWK 语句中的变量中,以便随后应用 gsub
吗?
Awk 简单地将每一行脚本应用于每一行输入。您可以轻松删除回车 return,然后将一些其他逻辑应用于输入行。例如,
FILENAME=$(awk '/\r/ { sub(/\r/, "") }
/DATAFILE/ { print }' "$INFILE")
另请注意When to wrap quotes around a shell variable。
使用 GNU awk
,请您尝试以下操作:
FILENAME=$(awk -v RS='\r?\n' '/DATAFILE/ {print }' "$INFILE")
echo "$FILENAME"
它将记录分隔符 RS
分配给一系列零或一 \r
后跟 \n
。
附带说明一下,不建议使用大写字母作为用户变量名,因为它可能与系统保留的变量名冲突。
文件名可以包含空格,包括 \r
s、空格和制表符,因此要稳健地执行此操作,您不能使用 gsub()
删除所有 \r
s,并且您可以不依赖于任何领域,例如</code>,包含整个文件名。</p>
<p>如果您的输入字段是 tab-separated 您需要:</p>
<pre><code>awk '/DATAFILE/ { sub(/[^\t]+\t/,""); sub(/\r$/,""); print }' file
或者这样:
awk '/DATAFILE/ { sub(/[^[:space:]]+[[:space:]]+/,""); sub(/\r$/,""); print }' file
以上假定您的文件名不以空格开头且不包含换行符。
要测试任何解决方案的稳健性,请尝试:
printf 'DATAFILE\tfoo \r bar\r\n' | awk '...' | cat -TEv
并确保输出如下所示:
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^\t]+\t/,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^[:space:]]+[[:space:]]+/,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
注意文件名中间的空格、^M
(CR) 和 ^I
(制表符),它们应该是这样的,但末尾没有 ^M
行。
如果您的 cat
版本不支持 -T
或 -E
,那么按照您通常所做的一切来查找 non-printing 字符,例如od -c
或 vi
输出。
谁说你需要 gnu-awk :
gecho -ne "test\r\nabc\n\rdef\n" \
\
| mawk NF=NF FS='\r' OFS='' | odview
0000000 1953719668 1667391754 1717920778 10
t e s t \n a b c \n d e f \n
164 145 163 164 012 141 142 143 012 144 145 146 012
t e s t nl a b c nl d e f nl
116 101 115 116 10 97 98 99 10 100 101 102 10
74 65 73 74 0a 61 62 63 0a 64 65 66 0a
0000015
gawk -P posix 模式也可以:
gecho -ne "test\r\nabc\n\rdef\n" \
\
| gawk -Pe NF=NF FS='\r' OFS='' | odview
0000000 1953719668 1667391754 1717920778 10
t e s t \n a b c \n d e f \n
164 145 163 164 012 141 142 143 012 144 145 146 012
t e s t nl a b c nl d e f nl
116 101 115 116 10 97 98 99 10 100 101 102 10
74 65 73 74 0a 61 62 63 0a 64 65 66 0a
0000015
我是 AWK 的新手,所以对于这个基本问题深表歉意。我找到了许多关于从文件中删除 windows 结束行字符但 none 匹配正则表达式并随后删除 windows 结束行字符的参考资料。
我有一个名为 infile.txt 的文件,其中包含如下一行:
...
DATAFILE data5v.dat
...
在 shell 脚本中,我想从此 infile.txt 捕获文件名参数 data5v.dat
并删除任何回车 return 字符,\r,如果存在。回车 return 可能并不总是存在。所以我必须匹配一个词,然后删除 \r 随后。
我尝试了以下方法,但没有达到我的预期效果:
FILENAME=$(awk '/DATAFILE/ { print gsub("\r", "", ) }' $INFILE)
我可以将匹配正则表达式 /DATAFILE/
的字符串 return 存储在我的 AWK 语句中的变量中,以便随后应用 gsub
吗?
Awk 简单地将每一行脚本应用于每一行输入。您可以轻松删除回车 return,然后将一些其他逻辑应用于输入行。例如,
FILENAME=$(awk '/\r/ { sub(/\r/, "") }
/DATAFILE/ { print }' "$INFILE")
另请注意When to wrap quotes around a shell variable。
使用 GNU awk
,请您尝试以下操作:
FILENAME=$(awk -v RS='\r?\n' '/DATAFILE/ {print }' "$INFILE")
echo "$FILENAME"
它将记录分隔符 RS
分配给一系列零或一 \r
后跟 \n
。
附带说明一下,不建议使用大写字母作为用户变量名,因为它可能与系统保留的变量名冲突。
文件名可以包含空格,包括 \r
s、空格和制表符,因此要稳健地执行此操作,您不能使用 gsub()
删除所有 \r
s,并且您可以不依赖于任何领域,例如</code>,包含整个文件名。</p>
<p>如果您的输入字段是 tab-separated 您需要:</p>
<pre><code>awk '/DATAFILE/ { sub(/[^\t]+\t/,""); sub(/\r$/,""); print }' file
或者这样:
awk '/DATAFILE/ { sub(/[^[:space:]]+[[:space:]]+/,""); sub(/\r$/,""); print }' file
以上假定您的文件名不以空格开头且不包含换行符。
要测试任何解决方案的稳健性,请尝试:
printf 'DATAFILE\tfoo \r bar\r\n' | awk '...' | cat -TEv
并确保输出如下所示:
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^\t]+\t/,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^[:space:]]+[[:space:]]+/,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
注意文件名中间的空格、^M
(CR) 和 ^I
(制表符),它们应该是这样的,但末尾没有 ^M
行。
如果您的 cat
版本不支持 -T
或 -E
,那么按照您通常所做的一切来查找 non-printing 字符,例如od -c
或 vi
输出。
谁说你需要 gnu-awk :
gecho -ne "test\r\nabc\n\rdef\n" \
\
| mawk NF=NF FS='\r' OFS='' | odview
0000000 1953719668 1667391754 1717920778 10
t e s t \n a b c \n d e f \n
164 145 163 164 012 141 142 143 012 144 145 146 012
t e s t nl a b c nl d e f nl
116 101 115 116 10 97 98 99 10 100 101 102 10
74 65 73 74 0a 61 62 63 0a 64 65 66 0a
0000015
gawk -P posix 模式也可以:
gecho -ne "test\r\nabc\n\rdef\n" \
\
| gawk -Pe NF=NF FS='\r' OFS='' | odview
0000000 1953719668 1667391754 1717920778 10
t e s t \n a b c \n d e f \n
164 145 163 164 012 141 142 143 012 144 145 146 012
t e s t nl a b c nl d e f nl
116 101 115 116 10 97 98 99 10 100 101 102 10
74 65 73 74 0a 61 62 63 0a 64 65 66 0a
0000015