【问题标题】:replacement on xargs variable returns empty stringxargs 变量的替换返回空字符串
【发布时间】:2017-11-17 06:47:48
【问题描述】:

我需要在目录树中搜索 XML 文件并在另一个目录 (staging_ojs_pootle) 上为它们创建链接,用文件路径命名这些链接(每个点替换斜线)。

bash 命令不起作用,我卡在替换部件上。似乎 xargs 中名为“file”的变量在替换代码(${file/\//.})中是不可访问的@

find directory/ -name '*.xml' | xargs  -I 'file' echo "ln" file staging_ojs_pootle/${file/\//.}

${} 结果中的替换给​​了我一个空字符串。

尝试使用 sed 但正则表达式正在替换全部或仅替换最后一个斜杠:/

 find directory/ -name '*.xml' | xargs  -I 'file' echo "ln" file staging_ojs_pootle/file |sed -e '/^ln/s/\(staging_ojs_pootle.*\)[\/]\(.*\)/\1.\2/g'

问候

【问题讨论】:

  • file 不是 shell 变量的名称,它是一个占位符,它被 xargs 替换为它正在处理的 XML 文件的名称。所以你不能在上面使用像${file...}这样的shell变量替换命令。如果您向我们展示一些示例输入和预期输出,我们可以为您提供帮助。

标签: string bash sed replace xargs


【解决方案1】:

试试这个:

$ find directory/ -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 staging_ojs_pootle/\1|e'

例如:

$ mkdir -p /tmp/test
$ touch {1,2,3,4}.xml
# use /tmp/test as staging_ojs_pootle
$ find /tmp/test -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 /tmp/test/\1|e'
$ ls -al /tmp/test
total 8
drwxr-xr-x. 2 root root 4096 Jun 15 13:09 .
drwxrwxrwt. 9 root root 4096 Jun 15 11:45 ..
-rw-r--r--. 2 root root    0 Jun 15 11:45 1.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 2.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 3.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 4.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 .tmp.test.1.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 .tmp.test.2.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 .tmp.test.3.xml
-rw-r--r--. 2 root root    0 Jun 15 11:45 .tmp.test.4.xml
# if don NOT use the e modifier of s command, we can get the final command
$ find /tmp/test -name '*.xml' |sed -r 'h;s|/|.|g;G;s|([^\n]+)\n(.+)|ln \2 /tmp/test/\1|' 
ln /tmp/test/1.xml /tmp/test/.tmp.test.1.xml
ln /tmp/test/2.xml /tmp/test/.tmp.test.2.xml
ln /tmp/test/3.xml /tmp/test/.tmp.test.3.xml
ln /tmp/test/4.xml /tmp/test/.tmp.test.4.xml

解释:

  1. 对于每个 xml 文件,使用 h 将原始文件名保留在 hold space 中。
  2. 使用s|/|.|g 将所有/ 替换为. 来替换xml 文件名。
  3. 使用Ghold space 附加到pattern space,然后pattern space 就是CHANGED_FILENAME\nORIGIN_FILENAME
  4. 使用s|([^\n]+)\n(.+)|ln \2 staging_ojs_pootle/\1|e'将命令与CHANGED_FILENAMEORIGIN_FILENAME合并,然后使用s命令的e修饰符执行上面组装的命令,就可以实际工作了。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    如果您可以确定您的 XML 文件的名称不包含任何分词字符,您可以使用类似的内容:

    find directory -name "*.xml" | sed 'p;s/\//./' | xargs -n2 echo ln
    

    【讨论】:

      猜你喜欢
      • 2020-06-19
      • 2020-09-15
      • 2021-10-20
      • 2020-07-13
      • 2012-06-03
      • 2013-09-18
      • 2013-02-16
      • 2023-03-15
      • 2020-07-09
      相关资源
      最近更新 更多