fixit7 Asked: 2020-06-14 18:08:17 +0800 CST2020-06-14 18:08:17 +0800 CST 2020-06-14 18:08:17 +0800 CST 将两个命令合并为一个命令 772 我正在寻找一种将这两者结合起来的方法,以便我可以从命令行一步完成。(我认为%1会在命令中。) convert Tess.jpg tess.tif tesseract tess.tif tess 例如: text2file name of scanned document 这是在 Ubuntu MATE 上。 scripts bash filename 4 个回答 Voted Best Answer Eliah Kagan 2020-06-14T19:09:23+08:002020-06-14T19:09:23+08:00 您表示您希望能够运行 text2file name-of-scanned-document 具有两个命令的效果: convert Tess.jpg tess.tif tesseract tess.tif tess 在这种情况下,您希望编写一个简单的脚本,或者定义一个 shell 函数。您提到您认为您所写的内容可能包含%1. 这就是 Windows(以及在此之前,DOS)批处理文件将使用传递给它的第一个命令行参数的方式,但在 Bash 中,位置参数是${1}, ${2},依此类推1(下面的{ }大括号是可选的${10})。所以你会写$1,不是%1。 要制作一个 shell 脚本,请使用您想要的命令名称 ( text2file) 创建一个文件,其中包含以下内容: #!/bin/bash convert "$1.jpg" "$1.tiff" tesseract "$1.tiff" "$1" $1扩展为传递给脚本的第一个命令行参数。这可能包含空格,只需确保在运行脚本时将其括在引号中。脚本本身中的双引号是为了防止不需要的分词和通配(这是进一步的扩展,否则会在参数扩展的结果上执行)。$1 如果您希望tesseract命令仅在convert成功时运行,则可以&&在命令后放置 a convert: #!/bin/bash convert "$1.jpg" "$1.tiff" && tesseract "$1.tiff" "$1" &&前面不能有换行符,但如果你愿意,它可以后面跟着一个,或者你可以删除它后面的换行符,如Giiba 的回答所示。也就是说,那里显示的技术是完全正确的(尽管它没有在编写脚本的上下文中出现)。 (&&实现这一目标的两种最流行的方法之一。另一种是set -e,在这种情况下可以正常工作,但在某些效果上可能非常不直观。) 然后通过运行标记您的脚本可执行文件: chmod +x text2file 然后,您可以使用包含至少一个/. 因此,从脚本所在的同一目录中: ./text2file name-of-scanned-document 为了能够在text2file任何地方运行它,请将文件放在$PATH环境变量中列出的目录中。我推荐~/bin(即bin直接位于主目录内的目录)。如果此目录不存在,您可以创建它。在所有后续登录时,它将$PATH自动添加到,因为~/.profile包含检查是否~/bin存在并将其添加到如果存在的代码$PATH。 然后你会运行: text2file name-of-scanned-document 对于您给出的示例,这只是: text2file tess $1扩展至以tess这种方式运行的时间,因此您不应该(实际上绝不能)tess在运行它之后编写文件类型后缀。two words下面是一个示例,说明当名称包含空格时如何运行它: text2file 'two words' 相反,如果您希望将其实现text2file为 shell 函数,则可以将此定义放在以下代码的底部~/.bashrc: text2file() { convert "$1.jpg" "$1.tiff" tesseract "$1.tiff" "$1" } 或者: text2file() { convert "$1.jpg" "$1.tiff" && tesseract "$1.tiff" "$1" } 然后在您随后启动的所有交互式 Bash shell 中,它将可用。如果你想在一个已经启动的 shell 中使用它,你可以 source ~/.bashrc( . ~/.bashrc),或者你可以直接在 shell 中运行那个函数定义(即上面显示的代码)。 使用交互式 Bash shell 时,运行它的方式与将其编写为脚本并将其放在$PATH. 1从技术上讲,位置参数本身就是 1(not $1or ${1})、2(not $2or ${2}) 等等。同样,您在技术上没有$PATH环境变量,因为环境变量被称为PATH. 与某些语言(例如,Perl、PowerShell)不同,前导$(以及随后的封闭{ },如果存在)实际上并不是参数或变量名称的一部分,而是用于触发参数扩展的语法。 Giiba 2020-06-14T18:28:13+08:002020-06-14T18:28:13+08:00 您可以使用 && 加入终端命令: <command 1> && <command 2> && <command 3> 因此,如果我理解正确,您希望: convert tess.jpg tess.tif && tesseract tess.tif tess Matthew Williams 2020-06-15T12:21:55+08:002020-06-15T12:21:55+08:00 构建一个简单的 bash 脚本可能是最好的选择。这里有一些很好的例子来说明从哪里开始。 TLDP.org Linux.com 具体看一下 Linux.com 变量部分。您甚至不需要构建函数,只需将命令与变量链接起来,这样您就可以使脚本更具可扩展性和可重用性。 Dluzak1 2020-06-15T13:56:02+08:002020-06-15T13:56:02+08:00 我会提出另一种解决方案。 convert Tess.jpg tif:- | tesseract stdin tess 这避免了创建中间文件 tess.tif 。相反,它将输出convert直接从管道传输到tesseract. 这有一些优点: 你不会用中间文件污染目录, 您不会对硬盘进行不必要的写入, 它可能会稍微快一些。 许多命令行工具能够从标准输入输出到标准输出/输入,而不是使用文件。对于那些convert,我在他们各自的页面tesseract中找到了如何做到这一点。man 可以通过其他方式将其变为命令: 创建一个shell脚本: echo '#!/bin/sh' > text2file echo 'convert "$1.jpg" tif:- | tesseract stdin "$1"' >> text2file chmod +x text2file ./text2file tess 这些命令将在当前目录中创建一个脚本,因此只能在当前目录中访问它。要使其在任何目录中都可以访问,您需要将其移动到~/.local/bin例如。通过使用命令mv text2file ~/.local/bin。之后它可以在任何目录中使用,例如: text2file tess 创建一个 bash 函数 echo 'text2file() {' >> ~/.bashrc echo 'convert "$1.jpg" tif:- | tesseract stdin "$1"' >> ~/.bashrc echo '}' >> ~/.bashrc 将无法立即访问。您需要使用source ~/.bashrc或仅打开新终端重新加载 .bashrc 配置。
您表示您希望能够运行
具有两个命令的效果:
在这种情况下,您希望编写一个简单的脚本,或者定义一个 shell 函数。您提到您认为您所写的内容可能包含
%1
. 这就是 Windows(以及在此之前,DOS)批处理文件将使用传递给它的第一个命令行参数的方式,但在 Bash 中,位置参数是${1}
,${2}
,依此类推1(下面的{
}
大括号是可选的${10}
)。所以你会写$1
,不是%1
。要制作一个 shell 脚本,请使用您想要的命令名称 (
text2file
) 创建一个文件,其中包含以下内容:$1
扩展为传递给脚本的第一个命令行参数。这可能包含空格,只需确保在运行脚本时将其括在引号中。脚本本身中的双引号是为了防止不需要的分词和通配(这是进一步的扩展,否则会在参数扩展的结果上执行)。$1
如果您希望
tesseract
命令仅在convert
成功时运行,则可以&&
在命令后放置 aconvert
:&&
前面不能有换行符,但如果你愿意,它可以后面跟着一个,或者你可以删除它后面的换行符,如Giiba 的回答所示。也就是说,那里显示的技术是完全正确的(尽管它没有在编写脚本的上下文中出现)。(
&&
实现这一目标的两种最流行的方法之一。另一种是set -e
,在这种情况下可以正常工作,但在某些效果上可能非常不直观。)然后通过运行标记您的脚本可执行文件:
然后,您可以使用包含至少一个
/
. 因此,从脚本所在的同一目录中:为了能够在
text2file
任何地方运行它,请将文件放在$PATH
环境变量中列出的目录中。我推荐~/bin
(即bin
直接位于主目录内的目录)。如果此目录不存在,您可以创建它。在所有后续登录时,它将$PATH
自动添加到,因为~/.profile
包含检查是否~/bin
存在并将其添加到如果存在的代码$PATH
。然后你会运行:
对于您给出的示例,这只是:
$1
扩展至以tess
这种方式运行的时间,因此您不应该(实际上绝不能)tess
在运行它之后编写文件类型后缀。two words
下面是一个示例,说明当名称包含空格时如何运行它:相反,如果您希望将其实现
text2file
为 shell 函数,则可以将此定义放在以下代码的底部~/.bashrc
:或者:
然后在您随后启动的所有交互式 Bash shell 中,它将可用。如果你想在一个已经启动的 shell 中使用它,你可以 source
~/.bashrc
(. ~/.bashrc
),或者你可以直接在 shell 中运行那个函数定义(即上面显示的代码)。使用交互式 Bash shell 时,运行它的方式与将其编写为脚本并将其放在
$PATH
.1从技术上讲,位置参数本身就是
1
(not$1
or${1}
)、2
(not$2
or${2}
) 等等。同样,您在技术上没有$PATH
环境变量,因为环境变量被称为PATH
. 与某些语言(例如,Perl、PowerShell)不同,前导$
(以及随后的封闭{
}
,如果存在)实际上并不是参数或变量名称的一部分,而是用于触发参数扩展的语法。您可以使用 && 加入终端命令:
因此,如果我理解正确,您希望:
构建一个简单的 bash 脚本可能是最好的选择。这里有一些很好的例子来说明从哪里开始。
TLDP.org Linux.com
具体看一下 Linux.com 变量部分。您甚至不需要构建函数,只需将命令与变量链接起来,这样您就可以使脚本更具可扩展性和可重用性。
我会提出另一种解决方案。
这避免了创建中间文件 tess.tif 。相反,它将输出
convert
直接从管道传输到tesseract
.这有一些优点:
许多命令行工具能够从标准输入输出到标准输出/输入,而不是使用文件。对于那些
convert
,我在他们各自的页面tesseract
中找到了如何做到这一点。man
可以通过其他方式将其变为命令:
这些命令将在当前目录中创建一个脚本,因此只能在当前目录中访问它。要使其在任何目录中都可以访问,您需要将其移动到
~/.local/bin
例如。通过使用命令mv text2file ~/.local/bin
。之后它可以在任何目录中使用,例如:将无法立即访问。您需要使用
source ~/.bashrc
或仅打开新终端重新加载 .bashrc 配置。