Unix:运行2个从管道获取输入的命令?

发布于 2024-09-14 12:29:37 字数 844 浏览 6 评论 0原文

更新: 感谢您的回答。正如我所说,我的 q 只是我的用例的翻译。 让我更详细地了解我想要实现的目标。 在我的开发环境中,我们使用“ade”作为版本控制系统,我想要做的是:

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | xargs -iF ade unbranch F 

现在,每次我运行 unbranch 命令时,都会检出一个新文件/目录。所以我需要在所有 unbranch 命令之后运行 ade checkin -all 。所以我需要类似有

"pre part till sort" | xargs -iF (ade unbranch + ade checkin -all) 

什么方法可以在管道操作上运行 2 个命令?

谢谢

原来的问题:

我可以将我的用例翻译成以下内容:

我需要获取文件的第一行。我

cat file | head -1 

现在想在文件列表上执行此操作。如何在一个 UNIX 命令中执行以下操作? 例如:

find . -name "*.log" | ( xargs -iF cat F  | head -1 )

显然上面命令中的括号不起作用。

有没有办法通过管道输出 find 命令的输出并对其执行 2 个命令( cat 和 head )?尝试使用;和&&但没有帮助。 我可以创建一个脚本 - 但想用一个命令来完成此操作。

再说一次——这只是我的案例的翻译。

谢谢 罗汉

Updated :
Thanks for your answers. As I said, my q was just a translation of my usecase.
Let me get into more details of what I want to achieve.
In my dev env, we use "ade" as our version control system what I want to do is :

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | xargs -iF ade unbranch F 

Now, every single time I run the unbranch command, a new file/dir gets checked out. so I need to run ade checkin -all after all my unbranch commands. So I needed something like

"pre part till sort" | xargs -iF (ade unbranch + ade checkin -all) 

Any way to run 2 commands on the op of pipe ?

Thanks

Original question asked :

I can translate the usecase I have into the following :

I need to get the 1st line of a file. I do

cat file | head -1 

Now I want to do this on a list of files. How do I do the following in one unix command ??
Eg :

find . -name "*.log" | ( xargs -iF cat F  | head -1 )

Obviously the brackets in the above command do not work.

is there a way to pipe the output of the find command and do 2 commands on it ( cat and head ) ? Tried using ; and && but dint help.
I can create a script - but wanted to do this in one command.

Again - this is just a translation of the case I have.

thanks
Rohan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鱼忆七猫命九 2024-09-21 12:29:38

通过将输入管道输入到 head 而不是简单地给它一个文件名,您使这比需要的更加复杂:

head -n1 `find -X . -name '*.log' | xargs`

如果您不需要遍历子目录,您可以使它甚至更简单:

head -n1 *.log

您可以通过 grep: | 管道来筛选出文件名标头grep -v '^(==> .* <==)?$' | grep -v '^$'

You're making this much more complicated than it needs to be, by piping input into head rather than simply giving it a filename(s):

head -n1 `find -X . -name '*.log' | xargs`

If you don't need to traverse subdirectories, you can make it even simpler:

head -n1 *.log

You can screen out the filename headers by piping through grep: | grep -v '^(==> .* <==)?$' | grep -v '^$'

兰花执着 2024-09-21 12:29:38

尝试

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | xargs sh -c 'ade unbranch "$@"; ade checkin -all "$@"' arg0

假设 ade 一次接受多个文件,并且需要为每个文件调用 ade checkin -all

字符串 arg0 提供 -c 字符串中 $0 的值。

Try

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | xargs sh -c 'ade unbranch "$@"; ade checkin -all "$@"' arg0

This is assuming that ade accepts multiple files at once and ade checkin -all needs to be called for every file.

The string arg0 supplies the value of $0 in the -c string.

隐诗 2024-09-21 12:29:38

我不知道ade,所以我必须猜测这两个命令想要什么
真的是跑都跑。但如果你有 GNU Parallel
http://www.gnu.org/software/parallel/ 应安装其中之一
work:

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ";" ade checkin -all {}

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ";" ade checkin -all

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ; ade checkin -all

如果ade可以并行运行,则可以删除-j1

观看 GNU Parallel 的介绍视频以了解更多信息:
http://www.youtube.com/watch?v=OpaiGYxkSuQ

I do not know ade, so I will have to guess what the 2 commands want
to run really are. But if you have GNU Parallel
http://www.gnu.org/software/parallel/ installed one of these should
work:

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ";" ade checkin -all {}

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ";" ade checkin -all

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr |
parallel -j1 ade unbranch {} ; ade checkin -all

If ade can be run in parallel, you can remove -j1.

Watch the intro video for GNU Parallel to learn more:
http://www.youtube.com/watch?v=OpaiGYxkSuQ

千年*琉璃梦 2024-09-21 12:29:37

首先,head 接受多个文件名,因此您可以简单地编写:

 head -q -n 1 *.log

或:

find . -name '*.log' -exec head -n 1 '{}' ';'

但是,如果您确实需要复制流,则使用 tee 并执行以下操作:

 wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) > dvd.iso

此示例取自 info coreutils 'tee inspiration'


更新(在ade评论之后)在您的情况下,tee将不起作用。您需要在另一个任务完成后执行一个任务,而 tee 将或多或少同时触发这些任务(模缓冲)。

另一种方法将起作用,只要输入行中没有空格(我知道这是一个严重的问题,但我现在不确定如何克服它)。我将从一个通用解决方案开始:

echo -e 'Foo\nBar\nBaz' | ( for i in `cat` ; do echo 1$i ; echo 2$i ; done )

这里,echo -e 'Foo\nBar\nBaz' 创建一个示例多行输入,echo 1$i 是第一个要运行的命令,echo 2$i 是第二个要运行的命令。

我不熟悉 ade ,并且我的系统上没有安装它,但我猜测在您的情况下,类似这样的操作可能会起作用:

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | ( for i in `cat` ; do ade unbranch $i ; ade checkin -all $i ; done )

First of all, head accepts more than one file name, so you can simply write:

 head -q -n 1 *.log

or:

find . -name '*.log' -exec head -n 1 '{}' ';'

However, if you really need to duplicate the stream, then use tee and do something along the lines of:

 wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) > dvd.iso

This example is taken from info coreutils 'tee invocation'.


UPDATE (Following the ade comment) In your case tee will not work. You need to perform a task after another task finishes, and tee will trigger the tasks more or less simultaneously (modulo buffering).

Another approach will work, provided that there are no spaces in the input lines (a serious issue, I know, but I'm not sure how to overcome it right now). I'll start with a generic solution:

echo -e 'Foo\nBar\nBaz' | ( for i in `cat` ; do echo 1$i ; echo 2$i ; done )

Here, echo -e 'Foo\nBar\nBaz' creates a sample multi-line input, echo 1$i is the first command to run, echo 2$i is the second command to run.

I'm not familiar with ade and I don't have it installed on my system, but I'm guessing that in your case something like this might work:

ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | ( for i in `cat` ; do ade unbranch $i ; ade checkin -all $i ; done )
瑕疵 2024-09-21 12:29:37

cat 的使用毫无用处。只需将文件名传递给 head:

find . -name '*.log' -exec head -n 1 '{}' '+'

find . -name '*.log' -print0 | xargs -0 head -n 1

EDIT: 这将打印每个文件的标题。在 Linux 上,可以使用 -q 来抑制这种情况,但在其他系统上,您必须确保使用单个参数调用 head

find . -name '*.log' -exec head -n 1 '{}' ';'

Useless use of cat. Simply pass the file names to head:

find . -name '*.log' -exec head -n 1 '{}' '+'

or

find . -name '*.log' -print0 | xargs -0 head -n 1

EDIT: This will print headers for each file. On Linux, this can be suppressed with -q, but on other systems you must make sure that head is called with a single argument:

find . -name '*.log' -exec head -n 1 '{}' ';'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文