如何用传递给Xargs的Shebang过滤文件?
TL; DR
我正在尝试编写一个简单的脚本,该脚本在给定文件夹和任何一个子文件夹中编译所有.swift
文件,但它不包括以Shebang开头的那些文件。
我正在尝试编写一个简单的实用程序的详细信息
,该实用程序将使我将多个Swift文件编译为单个编译的输出,而无需任何高级IDE或项目文件等。文件夹结构本身将是项目的定义,而root在i的位置i。查找main.swift
文件。
假设我已经找到了main.swift
and Am在ever Directory中,从查找
命令开始,我可以找到所有相关的swift文件,例如
find * -type f -name "*.swift"
...另一个答案在这里,通过附加-print0
,并将其馈送给XARGS -0
,它们都可以一口气发送到Swift编译器,就像这样...
find * -type f -name "*.swift" -print0 | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"
注意:多亏了
-print0
在上找到
命令和xargs -0
在另一侧,所有 n 参数同时以 同时传递给一个执行xcrun
的执行的xcrun
每个参数。只有一个汇编和一个输出文件。
问题是,如果将这些Swift文件中的任何一个设置为Swift脚本文件(即以Shebang开头的文件),则编译器会拒绝它们。它们也很可能包含顶级语句,除非它们在main.swift
中,否则编译器也不喜欢。
例如,如果这是在文件someutil
...
#! /usr/bin/env swift
print("Hello from Swift!")
...并且您ran chmod +x someutil
中,您现在可以像任何其他任何其他shell script一样执行swift文件只要它可以在路径中到达。
echo Here we go!
someutil
echo Done!
但是
Here we go!
Hello from Swift
Done!
,如果您将该文件发送到编译器,它将抱怨Shebang和关于不在main.swift
的顶级语句。
因此,我试图过滤掉以Shebang开头的任何发现的文件,基本上将其用作Swift脚本的标识符,以排除在外。
我已经看到了很多关于如何仅包括这些文件的GREP教程,但找不到任何排除它们,尤其是因为上述代码也取决于-print0
find命令本身(这意味着我无法轻易在其他地方进行过滤。)
所以这是可能的吗?
更新 - 使用Argchecker util验证。
这里的几个答案出现是正确的,但实际上并未正确处理参数。要检查这一点,我建议创建以下“ Argchecker”实用程序。只需创建一个带有以下内容的文件,在其上运行chmod +x
,然后将其添加到您的路径中。现在,您认为您认为有效的任何解决方案输出到argchecker
而不是xcrun
编译器行。在其中很多情况下,您会看到而不是“ n”参数,您将获得一个与所有预期的论点相连的参数。
文件'argchecker'
#! /usr/bin/env bash
echo "There are $# arguments:"
for ((i=1; i<=$#; i++))
do
echo " $i: ${!i}"
done
然后运行此...
chmod +x argchecker
并将其放在您的路径中。最后,在任何地方添加过滤器测试您的脚本。
find * -type f -name "*.swift" -print0 | xargs -0 argchecker
TL;DR
I'm trying to write a simple script that compiles all .swift
files in a given folder and any of it's subfolders, but which excludes those files that start with a shebang.
The Details
I'm trying to write a simple utility that will let me compile multiple Swift files into a single compiled output without requiring any advanced IDEs or project files, etc. The folder structure itself will be the project's definition with the root being wherever I find a main.swift
file.
Assuming I've already found main.swift
and am in the according directory, starting with the find
command, I can find all relevant Swift files like so...
find * -type f -name "*.swift"
Thanks to another answer here, by appending -print0
and feeding that to xargs -0
, they can all be sent to swift compiler in one fell swoop, like so...
find * -type f -name "*.swift" -print0 | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"
Note: thanks to the use of
-print0
on thefind
command andxargs -0
on the other side, all n arguments are passed in at the same time to one execution ofxcrun
, not n executions ofxcrun
with one argument each. There is only one compilation and one single output file.
The issue is if any of those Swift files are set up as Swift script files (i.e. those that start with a shebang), the compiler rejects them. They're also most likely to contain top-level statements, something the compiler also doesn't like unless they are in main.swift
.
For instance, if this is in the file someutil
...
#! /usr/bin/env swift
print("Hello from Swift!")
...and you ran chmod +x someutil
, you could now execute that Swift file like any other shell script so long as it's reachable in the path.
echo Here we go!
someutil
echo Done!
Output
Here we go!
Hello from Swift
Done!
However, if you send that file to the compiler, it will complain both about the shebang and about the top-level statements not being in main.swift
.
As such, I'm trying to filter out any of the found files which start with a shebang, using that basically as the identifier of Swift scripts to be excluded.
I've seen a lot of grep tutorials for how to include only those files, but can't find any that exclude them, especially since the above code also depends on the -print0
of the find command itself (meaning I can't easily do the filtering elsewhere.)
So is this possible?
Update - Verify with ArgChecker util.
Several of the answers here appear to be correct, but don't actually process the arguments correctly. To check this, I recommend creating the following 'argchecker' utility. Simply create a file with the following contents, run chmod +x
on it and add it to your path. Now make whatever solution you think works output to argchecker
instead of the xcrun
compiler line. In a lot of these you will see instead of 'n' arguments, you get a single argument with all the expected ones concatenated together.
File 'argchecker'
#! /usr/bin/env bash
echo "There are $# arguments:"
for ((i=1; i<=$#; i++))
do
echo " $i: ${!i}"
done
Then run this...
chmod +x argchecker
and put it in your path. Finally, test your script like this with the filtering added wherever.
find * -type f -name "*.swift" -print0 | xargs -0 argchecker
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
的输出来运行一个循环,查找
命令并运行grep
内部:详细信息:
查找。 -type f -name“*.swift” -print0
:查找*。swift
文件,并使用nul terminator&lt; &lt;(...)
是过程替换而ifs = read -rd''f
:从nul终止数据中读取输入。 ps:ifs =
和-d''
都是|| printf'%s \ 0'“ $ f”
仅在grep
命令失败时,才打印出具有NUL终端的文件名。| XARGS -0 XCRUN -SDK MACOSX SWIFTC -O“ $ output_file”
makexcrun
命令在最终输出时仅一次命令You can run a loop with output of
find
command and run agrep
inside:Details:
find . -type f -name "*.swift" -print0
: finds*.swift
files and prints them with a NUL terminator< <(...)
is process substitutionwhile IFS= read -rd '' f
: Make while loop read input from NUL terminated data. PS: bothIFS=
and-d ''
are required|| printf '%s\0' "$f"
prints file names with NUL terminator only whengrep
command fails.| xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"
makesxcrun
command only once on final output of while loop您也许可以进行优化。我假设像任何普通的UNIX一样,脚本具有可执行的权限,在这种情况下,您可以执行
此操作。 > -perm- )用户使用execute(
u+x
)。You may be able to make an optimization. I'm assuming like any normal Unix, scripts have executable permissions, in which case you could do
This means match any file that does not (
!
) have permissions (-perm -
) of user with execute (u+x
).可以使用
grep
<代码>查找和xcrun
:grep
选项:-l </code >:抑制正常输出;取而代之的是打印每个输入文件的名称,通常不会从中打印任何输出
-z
:输出一个零字节(assii nul carnem),而不是通常遵循文件名的字符。说明:
第一步
返回所有被NUL字符分开的发现的文件。请参阅:
输出:
^@
是漂亮的印刷nul chars第二步
xargs
谁接受Nul Char的分离元素(-0)
选项),在每个元素上启动grep
命令。grep
仅返回文件(-l </code>或
-l </code>选项),他们不包含令牌(
-L
选项)并通过nul char分开每个结果(-z
选项)。查看他们:输出:
警告:
^#! /usr/bin/env Swift $
如果完全按照您的需求;GREP
命令在MacOS上运行,请检查-L
和-Z
选项与GNUGREP 在Linux或其他系统下。
第三步
-Z | cat -v与第二步相同,除了执行
xcrun
命令输出:
警告:
^#! /usr/bin/env Swift $
如果完全按照您的需求;GREP
命令在MacOS上运行,请检查-L
和-Z
选项与GNUGREP 在Linux或其他系统下。
第三步
-Z | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"与第二步相同,除了执行
xcrun
命令grep
选项:-l </code >:抑制正常输出;取而代之的是打印每个输入文件的名称,通常不会从中打印任何输出
-z
:输出一个零字节(assii nul carnem),而不是通常遵循文件名的字符。说明:
第一步
返回所有被NUL字符分开的发现的文件。请参阅:
输出:
^@
是漂亮的印刷nul chars第二步
xargs
谁接受Nul Char的分离元素(-0)
选项),在每个元素上启动grep
命令。grep
仅返回文件(-l </code>或
-l </code>选项),他们不包含令牌(
-L
选项)并通过nul char分开每个结果(-z
选项)。查看他们:输出:
警告:
^#! /usr/bin/env Swift $
如果完全按照您的需求;GREP
命令在MacOS上运行,请检查-L
和-Z
选项与GNUGREP 在Linux或其他系统下。
第三步
-Z与第二步相同,除了执行
xcrun
命令xargs
谁接受Nul Char的分离元素(-0)
选项),在每个元素上启动grep
命令。grep
仅返回文件(-l </code>或
-l </code>选项),他们不包含令牌(
-L
选项)并通过nul char分开每个结果(-z
选项)。查看他们:输出:
警告:
^#! /usr/bin/env Swift $
如果完全按照您的需求;GREP
命令在MacOS上运行,请检查-L
和-Z
选项与GNUGREP 在Linux或其他系统下。
第三步
-Z | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"与第二步相同,除了执行
xcrun
命令grep
选项:-l </code >:抑制正常输出;取而代之的是打印每个输入文件的名称,通常不会从中打印任何输出
-z
:输出一个零字节(assii nul carnem),而不是通常遵循文件名的字符。说明:
第一步
返回所有被NUL字符分开的发现的文件。请参阅:
输出:
^@
是漂亮的印刷nul chars第二步
xargs
谁接受Nul Char的分离元素(-0)
选项),在每个元素上启动grep
命令。grep
仅返回文件(-l </code>或
-l </code>选项),他们不包含令牌(
-L
选项)并通过nul char分开每个结果(-z
选项)。查看他们:输出:
警告:
^#! /usr/bin/env Swift $
如果完全按照您的需求;GREP
命令在MacOS上运行,请检查-L
和-Z
选项与GNUGREP 在Linux或其他系统下。
第三步
与第二步相同,除了执行
xcrun
命令May be with a
grep
command betweenfind
andxcrun
:grep
option:-L
: Suppress normal output; instead print the name of each input file from which no output would normally have been printed-Z
: Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name.Explanations:
1st step
Return all found files separated by NUL character. See them with:
Output:
^@
are pretty printed NUL chars2nd step
xargs
who accept separated elements by NUL char (-0
option), launchgrep
command on each element.grep
returns file only (-l
or-L
option) who DO NOT contains token (-L
option) and separate each results by NUL char (-Z
option). See them with:Output:
Warning:
^#! /usr/bin/env swift$
if exactly as you want;grep
command, check if-L
and-Z
options are same as GNUgrep
under Linux or other systems.3rd step
-Z | cat -vSame as 2nd step except to execute
xcrun
commandOutput:
Warning:
^#! /usr/bin/env swift$
if exactly as you want;grep
command, check if-L
and-Z
options are same as GNUgrep
under Linux or other systems.3rd step
-Z | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"Same as 2nd step except to execute
xcrun
commandgrep
option:-L
: Suppress normal output; instead print the name of each input file from which no output would normally have been printed-Z
: Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name.Explanations:
1st step
Return all found files separated by NUL character. See them with:
Output:
^@
are pretty printed NUL chars2nd step
xargs
who accept separated elements by NUL char (-0
option), launchgrep
command on each element.grep
returns file only (-l
or-L
option) who DO NOT contains token (-L
option) and separate each results by NUL char (-Z
option). See them with:Output:
Warning:
^#! /usr/bin/env swift$
if exactly as you want;grep
command, check if-L
and-Z
options are same as GNUgrep
under Linux or other systems.3rd step
-ZSame as 2nd step except to execute
xcrun
commandxargs
who accept separated elements by NUL char (-0
option), launchgrep
command on each element.grep
returns file only (-l
or-L
option) who DO NOT contains token (-L
option) and separate each results by NUL char (-Z
option). See them with:Output:
Warning:
^#! /usr/bin/env swift$
if exactly as you want;grep
command, check if-L
and-Z
options are same as GNUgrep
under Linux or other systems.3rd step
-Z | xargs -0 xcrun -sdk macosx swiftc -o "$OUTPUT_FILE"Same as 2nd step except to execute
xcrun
commandgrep
option:-L
: Suppress normal output; instead print the name of each input file from which no output would normally have been printed-Z
: Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name.Explanations:
1st step
Return all found files separated by NUL character. See them with:
Output:
^@
are pretty printed NUL chars2nd step
xargs
who accept separated elements by NUL char (-0
option), launchgrep
command on each element.grep
returns file only (-l
or-L
option) who DO NOT contains token (-L
option) and separate each results by NUL char (-Z
option). See them with:Output:
Warning:
^#! /usr/bin/env swift$
if exactly as you want;grep
command, check if-L
and-Z
options are same as GNUgrep
under Linux or other systems.3rd step
Same as 2nd step except to execute
xcrun
command