bash 中这个奇怪的符号“:>”是什么意思

bash 中这个奇怪的符号“:>”是什么意思

我在脚本中发现了一些不属于主脚本的内容。:>排成一行。

你能向我解释一下这是什么意思吗?

:> file
while read A B C D E; do echo "$A;$B;$D;$E;$C" >> file; done < otherfile

答案1

bash 脚本中有一行 :>。这是什么意思?

:> file

这是一种简洁的说法:

  • 如果file不存在则创建它,否则将其截断为0字节。

这意味着您可以确定它file存在并且是空的。

您也可以使用,> file:> file便携性更强。

请参阅 Stack Overflow 问题GNU Bash Builtin 中的“:”(冒号)有什么用途?了解更多信息。

答案2

这看起来像是一种创建新文件的奇特方式。其中bash :有一个空命令:

$ type : 
: is a shell builtin 
$ help : 
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

>将输出重定向:到文件。

答案3

:是 的另一个名称true。两者都是 bash 中的 shell 内建命令,但没有/bin/:,只有/bin/true。输出重定向会导致 shell 转到open(2)带有 的文件O_CREAT|O_TRUNC。如果没有写入任何内容,则其长度为零。

将这两部分放在一起,:> file是截断文件的一个相当常见的习惯用法。不过,大多数人会尝试通过编写来使其看起来不那么奇怪: >file


由于您在评论中询问第二行,我会将我的评论转化为答案。(即使您没有在问题中问这个问题。)

第二行是一个循环,它将行从 读otherfile入一些命名变量。循环体使用分隔符而不是之前的空格来 echo打印它们。每次迭代都会关闭并重新打开(用于附加),因为重定向在循环内部。使用会更省力,并且避免需要先截断文件。不作为转义符。;filewhile ...;do read -r ...;done <otherfile >fileread -r\

Bash 中的文本处理速度非常慢。部分原因是不可避免的:read必须一次处理一个字节(read(2)每个字节一个系统调用)以避免超出行尾。最好使用正确的工具来完成这项工作:

awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile  >file

--意味着即使将脚本otherfile命名为诸如 之类的愚蠢名称,也不会中断--version

将输出字段分隔符设置为;意味着您可以将多个字段作为参数传递以进行打印。 Shellread将整行的其余部分连同空格一起分配给最后一个变量,但无法告诉 awk 只拆分为 5 个。 如果这很重要,也许只需继续使用 bash 循环,因为它在 awk 中不方便。 Perl 使这变得容易,因为它split可以接受最大字段参数,但启动速度比 awk 慢得多。

实际上,这并不难,只是一个难写的正则表达式。为了获取行的其余部分而不是$5在 awk 中,循环遍历字段仍然会丢失其原始空格。我的第一个可行想法是使用gensubon $0(整行)删除前 4 个字段(即非空格后跟空格),保留其他所有内容:

awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file

我第一次尝试就做对了,但我对自己印象深刻的事实说明了 awk 代码的可读性。>.<

请注意,它print与之前相同,但是用tail代替$5

echo 'A  B c DD    e      f g    f' | 
  awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
   print $1, $2, $4, tail, $3 }'

A;B;DD;e       f g    f;c

如果我可以复制/粘贴文字并显示它在输出中出现,这将更令人印象深刻。在 bash 中使用 ^Q 输入一个。ctrl-Q 表示将下一个按键引用为文字字符,因为 bash 的 emacs 样式行编辑与实际 emacs 相同。

http://mywiki.wooledge.org/BashFAQ有一些关于脚本的有用内容,无论您在脚本中输入什么数据或文件名,都不会中断。

相关内容