Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何将shell命令应用于命令输出的每一行?_Bash - Fatal编程技术网

Bash 如何将shell命令应用于命令输出的每一行?

Bash 如何将shell命令应用于命令输出的每一行?,bash,Bash,假设我有一个命令的一些输出(例如ls-1): 我想依次对每一个应用一个命令(比如echo)。例如 echo a echo b echo c echo d echo e ... 在bash中最简单的方法是什么?您可以使用: 以*存档;做 回显“$file” 完成 请注意,如果有问题的命令接受多个参数,那么使用几乎总是更有效,因为它只需生成有问题的实用程序一次而不是多次。您可以在每一行上使用基本的前置操作: ls -1 | while read line ; do echo $line ; don

假设我有一个命令的一些输出(例如
ls-1
):

我想依次对每一个应用一个命令(比如
echo
)。例如

echo a
echo b
echo c
echo d
echo e
...
在bash中最简单的方法是什么?

您可以使用:

以*存档;做 回显“$file” 完成
请注意,如果有问题的命令接受多个参数,那么使用几乎总是更有效,因为它只需生成有问题的实用程序一次而不是多次。

您可以在每一行上使用基本的前置操作:

ls -1 | while read line ; do echo $line ; done
或者,您可以通过管道将输出传输到sed,以进行更复杂的操作:

ls -1 | sed 's/^\(.*\)$/echo \1/'

它可能是最容易使用的
xargs
。就你而言:

ls -1 | xargs -L1 echo
-L
标志确保正确读取输入。从
xargs
的手册页:

-L number
    Call utility for every number non-empty lines read. 
    A line ending with a space continues to the next non-empty line. [...]
如果cmd具有较大的输出:

cmd | xargs -L1 echo
您实际上可以使用sed来完成这项工作,只要它是GNU-sed的

... | sed 's/match/command \0/e'
工作原理:

  • 用命令匹配替换匹配
  • 替换时执行命令
  • 用命令输出替换替换替换的行
  • 对我来说更好的结果:

    ls -1 | xargs -L1 -d "\n" CMD
    

    xargs失败,带有反斜杠和引号。它应该是这样的

    ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
    
    xargs-0选项:

    ls-1
    使用换行符终止项目,因此
    tr
    将它们转换为空字符


    这种方法比使用
    手动迭代……
    要慢50倍左右(参见Michael Aaron Safyans的答案)(3.55s vs.0.066s)。但对于其他输入命令,如locate、find、从文件读取(
    tr\\n\\0例如,我喜欢使用gawk在列表上运行多个命令

    ls -l | gawk '{system("/path/to/cmd.sh "$1)}'
    

    但是,可转义字符的转义可能会有点麻烦。

    sed命令似乎不起作用:
    sh:cho:notfound一个sh:cho:notfound
    看起来像是将echo中的
    e
    当作sed命令或其他东西。
    while
    循环中的+1。
    cmd1;while read line;do cmd2$line;done
    读取行时;执行cmd2$line;完成<@Alex:将双引号更改为单引号。在while循环中引用
    中的“$line”
    ,以避免分词。尝试使用
    读取-r行
    以防止
    读取
    混淆转义字符。例如,
    echo'“a\”嵌套的“Quote”|读取行时;执行echo“$line”done
    提供了一个“嵌套的”引号“
    ,该引号已丢失转义。如果在读取-r行时执行
    回显''a\'nested\'quote';执行回显'$line'done
    则会执行
    的“嵌套的”引号"
    如预期。查看
    cmd
    的输出中是否有空格,第一个将失败。条目#1
    ls
    在管道中自动执行
    -1
    。@Dennis,看起来不像:
    ls | xargs-L2 echo
    ls-1 | xargs-L2 echo
    给出两个不同的输出。前者都在一行。
    xargs
    >只能运行可执行文件,而不是shell函数或shell内置命令。对于前者,最好的解决方案可能是在循环中使用
    read
    。我希望这个答案包括解释
    -L1
    的用途,-L,-max-lines=max-lines在每个命令行中最多使用max-lines非空输入行。-这意味着xa带有-L1的rgs每次都将执行一个消耗一行的命令。太棒了。我忘了将e命令放在末尾,但在看到您的回复后这样做了,它起作用了。当SED与一行匹配时,我试图添加一个1000到15000之间的随机ID。
    cat/logs/lfa/Modified.trace.log.20150904.pw|SED-r的s/^(.*)(\| 006\|00032\|)(.*)$/echo“\1\2\3-ID`shuf-i999-14999-n1”/e'
    值得描述xargs的正确/安全使用,即
    printf“%s\0”*| xargs-0…
    ——否则,使用带有空格、引号等的文件名是非常不安全的。更好,但并不完美。
    find.-mindepth 1-maxdepth 1-print0 | xargs-0命令将处理
    ls-1
    输出不明确的情况ous;如果您不希望在每个文件上都有一个前导的
    /
    ,请使用
    -printf“%P\0”
    ,而不是
    -print0
    ls-1
    可能是一个示例,但重要的是要记住,解析
    ls
    的输出是不好的。请参阅:
    ls -1 | xargs -L1 -d "\n" CMD
    
    ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
    
    -0, --null
              Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
              not special (every character is taken literally).  Disables the end of file string, which is treated  like
              any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
              GNU find -print0 option produces input suitable for this mode.
    
    ls -l | gawk '{system("/path/to/cmd.sh "$1)}'