使Linux的SPLIT命令与Mac OS终端兼容

4

我有一个在Linux上运行良好的Bash脚本,但当我在Mac终端上运行它时,由于Mac终端中split命令的选项略有不同,因此它会失败。我的脚本如下:

## Merge and half final two segments
last_file=`ls temp_filt.snplist_* | tail -n 1`
penultimate_file=`ls temp_filt.snplist_* | tail -n 2 | head -1`
cat $penultimate_file $last_file > temp && mv temp $penultimate_file
split -n l/2 $penultimate_file && mv xaa $penultimate_file; mv xab $last_file

脚本在最后一行失败,因为在Mac OS 10.x.x中的默认shell环境tcsh中不存在“-n l/2”选项。我想知道在tcsh中等效的脚本是什么。
是否有通用的方法可以在Mac OS终端中运行Linux脚本,而无需更改脚本?

在Mac OS中,tcsh已经不是默认的shell超过十年了(尽管它可能是您的默认shell)。 - chepner
@chepner:您好,这里说的是什么?https://dev59.com/zWsz5IYBdhLWcg3wNVAR#8051196 - RJF
正确;如果帐户在多个操作系统更新之间保留,则仍然可以将tcsh作为登录shell,但我建议切换到bash(或至少是符合POSIX标准的其他shell)。 - chepner
2个回答

6

这不是MacOS终端在执行split,而是一个名为split的程序。MacOS是基于FreeBSD用户空间工具构建的,其行为与GNU utils不同。

有两个选项:

  • 在Linux机器上安装FreeBSD工具,使它们与FreeBSD兼容。

  • 在您的MacOS机器上安装GNU utils。如果您有brew,您可以使用brew install coreutils来完成此操作。


2
coreutils 不会替换 MacOS 上的 FreeBSD 工具,而是添加了一个 'g' 前缀。例如:gsplit如果您需要使用这些命令的正常名称,可以像下面这样从 bashrc 添加 "gnubin" 目录到您的 PATH 中: PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - marengaz

1
一种选择是使用语言内置功能并限制外部命令。
请注意,脚本包含多个缺陷:ls 命令无用,解析 ls 输出不安全。
array=(temp_filt.snplist_*)
last_file=${array[ -1]}
penultimate_file=${array[ -2]}

如果文件很大,bash read内置函数将非常缓慢。
在这种情况下,可以使用兼容各系统的cat、wc、head和tail的简单解决方案。注意,在传递命令变量时,必须使用双引号以避免单词拆分。
cat "$penultimate_file" "$last_file" > temp || exit 1
nb_lines=$(wc -l < temp)
((half_nb_lines=nb_lines/2))
head "-$half_nb_lines" temp > "$penultimate_file" || exit 1
tail "+$((half_nb_lines+1))" temp > "$last_file" || exit 1
rm temp

在最后一行注释。
command1 && command2 ; command3

无论第一个退出状态如何,都会执行command3命令,可以使用{;}来对命令进行分组。
command1 && { command2 ; command3; }

非常感谢您的建议,真的很有帮助! - RJF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接