从 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
附带说明一下,不建议使用大写字母作为用户变量名,因为它可能与系统保留的变量名冲突。

文件名可以包含空格,包括 \rs、空格和制表符,因此要稳健地执行此操作,您不能使用 gsub() 删除所有 \rs,并且您可以不依赖于任何领域,例如</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 -cvi 输出。

谁说你需要 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