如何在bash中将`dos2unix`导入`read read`?

Pat*_*ter 0 bash dos2unix

现在,我正在尝试修复PrintBans.sh脚本中的问题.

问题是,生成这个文件的程序用\ r \n行结尾保存它,所以我需要while循环才能读取\ r \n行,否则在最后一行的末尾有一个额外的\ r \n导致算术失败:

 - 621355968000000000")syntax error: invalid arithmetic operator (error token is "
Run Code Online (Sandbox Code Playgroud)

我试过这些.

while read ban
do
    ...
done < dos2unix $file

while read ban
do
    ...
done < `dos2unix $file`

cat $file > dos2unix > while read ban
do
    ...
done

while read ban
do
    ...
done < dos2unix < $file
Run Code Online (Sandbox Code Playgroud)

我也看到有些人定了IFS='\r\n',但这对我不起作用.

是否无法在不覆盖原始文件的情况下通过dos2unix管道文件?

Cha*_*ffy 5

直译:直通!

如果您没有告诉dos2unix它正在使用的文件的名称,则它无法就地修改该文件.

while IFS= read -r line; do
  echo "No carriage returns here: <$line>"
done < <(dos2unix <"$file")
Run Code Online (Sandbox Code Playgroud)

重定向由shell在程序启动之前执行,当您调用时 dos2unix <input.txt,shell input.txtdos2unix 使用无参数调用之前用读取句柄替换文件描述符0 .

如果你想成为真正的偏执(和付出代价的偏执性能为代价),可以防止修正的接收上就地标准输入从通过使这样一个文件描述符一个假设不存在DOS2UNIX的<(cat <"$file" | dos2unix),使得dos2unix从FIFO读连接到单独的可执行文件cat,而不是直接从输入文件.不用说,我从来没有在实践中提出这个建议.


更好的答案:不要

您不需要dos2unix(具有默认的就地修改行为 - 适用于人类交互式用户,而不是脚本); shell本身可以为您删除回车:

#!/usr/bin/env bash
#              ^^^^- not /bin/sh; needed for $'' syntax and [[ ]]

while IFS= read -r line || [[ $line ]]; do
  line=${line%$'\r'}
  echo "No carriage returns here: <$line>"
done <"$file"
Run Code Online (Sandbox Code Playgroud)
  • ${var%expr}是一个参数扩展,它expr从变量的内容中去除glob表达式的任何尾随实例var.
  • $'\r'是回车符的ANSI C类字符串语法.使用该语法很重要,因为看起来像是可能引用回车符的其他东西则不然.

    • \r在任何一种引用语境之外只是信r.
    • "\r"或者'\r'是两个字符(反斜杠然后是字母r),而不是一个回车符.
  • [[ $line ]]是bash所采用的ksh扩展等价于[ -n "$line" ]; 它检查变量line是否为非空.read如果你有一条没有任何终止符的部分行,那么在仍然填充一行时可能会返回false; 正如l0b0指出的那样,行分隔符而不是终结符在Windows上很常见.这样可确保处理文件的最后一行,即使它不以换行符结尾也是如此.