xargs不适用于SUSE

时间:2017-02-10 16:59:51

标签: bash sed xargs suse

  

此问题仅发生在上,它可以在ubuntu上运行,甚至可以通过在Windows上运行

我的观点是用另一个单词替换多个文件中的单词。

这就是我正在尝试的:

$  grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs sed -i 's/MY_PATTERN/NEW_WORD/g'

sed: can't read path/to/a/found/file_1: No such file or directory
sed: can't read path/to/a/found/file_2: No such file or directory
sed: can't read path/to/a/found/file_3: No such file or directory
...

知道

$  grep -Inrs MY_PATTERN src/ | cut -d: -f1
path/to/a/found/file_1
path/to/a/found/file_2
path/to/a/found/file_3

UPDATE1

这不起作用

$  grep -lZ -Irs MY_PATTERN src/ | xargs -0 ls

ls: cannot access path/to/a/found/file_1: No such file or directory
ls: cannot access path/to/a/found/file_2: No such file or directory
ls: cannot access path/to/a/found/file_3: No such file or directory
...

$ ls -al path/to/a/found/file_1 | cat -vet
-rw-r--r-- 1 webme 886 Feb  1 13:36 path/to/a/found/file_1$

UPDATE2

$ whoami
 webme

$ uname -a
 Linux server_vm_id_34 3.0.101-68-default #1 SMP Tue Dec 1 16:21:37 UTC 2015 (ed01a9f) x86_64 x86_64 x86_64 GNU/Linux

UPDATE3

$ grep --version
grep (GNU grep) 2.7
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.


$ xargs --version
xargs (GNU findutils) 4.4.0
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b

# My project path /home/users/webme/projects/my_project
$ df -T
 dl360d-01:/homeweb/users/webme nfs   492625920 461336576  31289344  94% /home/users/webme

$ id
 uid=1689(webme) gid=325(web) groups=325(web)

$ mount -v
/dev/vda2 on / type btrfs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,mode=1777)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/vda1 on /boot type ext3 (rw,acl,user_xattr)
/dev/vdb on /appwebinet type xfs (rw)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
dl360d-01:/homeweb/users on /homeweb/users type nfs (rw,soft,bg,addr=xx.xx.xx.xx)
dl360d-01:/appwebinet/tools/list on /appwebinetdev/tools/list type nfs (ro,soft,sloppy,addr=xx.xxx.xx.xx)
dl360d-01:/homeweb/users/webme on /home/users/webme type nfs (rw,soft,bg,addr=xx.xxx.xx.xx)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
none on /var/lib/ntp/proc type proc (ro,nosuid,nodev)

我没有exportfs,我也没有sudo zypper install exportfs

2 个答案:

答案 0 :(得分:3)

我建议保持简单:

$ grep -lZ -Irs foo * | xargs -0 sed -i 's/foo/bar/g'

grep -l仅输出匹配的文件名,这正是您在此管道中所需的内容。 grep -Z使用NUL终止每个匹配的文件名,xargs -0可以选择# show the structure $ tree . └── path └── to └── a └── found ├── file_1 ├── file_2 └── file_3 # show the contents $ grep . path/to/a/found/file_* path/to/a/found/file_1:a foo bar path/to/a/found/file_2:a foo bar path/to/a/found/file_3:a foo bar # try it out $ grep -lZ -Irs foo * | xargs -0 ls -l -rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_1 -rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_2 -rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_3 。这允许具有嵌入式空格的文件名在grep和不受限制的xargs之间传递。

<?php
class Node{
    public $left,$right;
    public $data;
    function __construct($data)
    {
        $this->left=$this->right=null;
        $this->data = $data;
    }
}
class Solution{
    public function insert($root,$data){
        if($root==null){
            return new Node($data);
        }
        else{
            if($data<=$root->data){
                $cur=$this->insert($root->left,$data);
                $root->left=$cur;
            }
            else{
                $cur=$this->insert($root->right,$data);
                $root->right=$cur;
            }
            return $root;
        }
    }
    public function getHeight($root) {
        $heightLeft = 0;
        $heightRight = 0;

        if ($root->left != null) {
            $heightLeft = getHeight($root->left) + 1;
        }
        if ($root->right != null) {
            $heightRight = getHeight($root->right) + 1;
        }
        echo "heightRigh is $heightRight\n";
        echo "heightLeft is $heightLeft\n";

        $ans = ($heightLeft > $heightRight ? $heightLeft : $heightRight);
        return $ans;
    }

}//End of Solution
$myTree=new Solution();
$root=null;
$T=intval(fgets(STDIN));
while($T-->0){
    $data=intval(fgets(STDIN));
    $root=$myTree->insert($root,$data);
}
$height=$myTree->getHeight($root);
echo $height;
?>

答案 1 :(得分:1)

在这种情况下,

bishop's helpful answer是最简单,最强大的解决方案 答案可能仍有兴趣(a)讨论-d-n选项,以及(b)如何预览 xargs将执行的命令。 功能

根据我的理解,SUSE使用 GNU 实用程序,因此您可以使用xargs -d'\n'

grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs -d'\n' sed -i 's/MY_PATTERN/NEW_WORD/g'

xargs -d'\n'确保每个输入行作为一个整体被视为自己的参数(保留带空格的文件名的完整性),同时仍然一次传递尽可能多的参数(通常是所有

(相比之下,-n 1将通过空格中断参数,并且一次使用1个参数调用目标命令。)

如果您想 预览 执行的命令,请使用辅助功能。 bash命令:

grep -Inrs MY_PATTERN src/ | cut -d: -f1 |
  xargs -d'\n' bash -c 'printf "%q " "$@"' _ sed -i 's/MY_PATTERN/NEW_WORD/g'

继续阅读以获得解释。

可选背景信息。

xargs有自己的选项 -p ,用于预览执行提示确认的命令,但预览不会以直接从 shell 调用命令时指示它们的方式反映参数边界

一个简单的例子:

$ echo 'hi, there' | xargs -p -d '\n' printf '%s'
printf %s hi, there ?...

实际执行的xargsprintf '%s' 'hi, there'等效,但反映在{ {1}}提示。

解决方法:

-p

通用辅助$ echo 'hi, there' | xargs -d '\n' bash -c 'printf "%q " "$@"' _ printf '%s' printf %s hi\,\ there 命令 - bash,在目标命令之前插入 - 引用 bash -c 'printf "%q " "$@"' _传递的参数 - 仅在必要时 - 以 shell 所需的方式将每个单个参数识别为,并将它们与空格连接。

最终结果是打印了 a shell命令,它是xargs将执行的等效 (但是,如您所见,无法保证保留输入引用样式。