String 如何将字符串拆分为变量/参数以传递给另一个脚本?

String 如何将字符串拆分为变量/参数以传递给另一个脚本?,string,bash,awk,tokenize,perl,String,Bash,Awk,Tokenize,Perl,我有一个文件列表(带有完整路径),我需要将这些文件拆分为令牌,以便能够传递给另一个脚本/命令。从字符串的样式来看,我认为awk是正确的工具,但鉴于令牌的数量因行而异,我似乎不知道如何使用它 给定一个文件名/some/path/to/artifact\u name/v1.2.3/filename.jar,我需要能够提取以下内容: filename-最后一个/:filename.jar后面的字符串 版本-文件名后面/前面的字符串:v1.2.3 artifact name-版本后面/前面的字符串:a

我有一个文件列表(带有完整路径),我需要将这些文件拆分为令牌,以便能够传递给另一个脚本/命令。从字符串的样式来看,我认为awk是正确的工具,但鉴于令牌的数量因行而异,我似乎不知道如何使用它

给定一个文件名
/some/path/to/artifact\u name/v1.2.3/filename.jar
,我需要能够提取以下内容:

  • filename-最后一个/:filename.jar后面的字符串
  • 版本-文件名后面/前面的字符串:v1.2.3
  • artifact name-版本后面/前面的字符串:artifact\u name
  • 组名-路径的其余部分,全部/替换为:一些
例如,假设:

./com/eric/ics/BillP/3.5.11/BillP-3.5.11.jar
- filename: BillP-3.5.11.jar
-version: 3.5.11
-artifact: BillP
-group: com.eric.ics
我最大的麻烦是,代表组的文件夹数量可能会发生变化。例如:
/com/eric/some/other/pkg/BillP/3.5.11/BillP-3.5.11.jar
将同样有效,但组将是
com.eric.some.other.pkg


我的目标是,一旦我成功地提取了这4个参数,就将它们传递给一个单独的脚本,但我似乎无法找到最简单的方法。awk是用于此的正确工具吗?有更好/更容易使用的吗?

您可以使用awk或perl打印所有组件,并将其导入
read
以将其分配给不同的变量名,或者使用不太优雅的命令
dirname
basename
多次逐个获取组件,将它们立即存储到变量中,可以用作调用其他脚本的参数。取决于你喜欢什么

#!/bin/bash

p="$1"
file="$(basename "$p")"
p="$(dirname "$p")"
version="$(basename "$p")"
p="$(dirname "$p")"
artifact="$(basename "$p")"
group="$(dirname "$p" | tr / . | sed 's+\.*++')"

echo file=$file version=$version artifact=$artifact group=$group
现在您有了4个变量中的4个参数,您可以将它们传递给任何您喜欢的对象。

使用gnu awk:

awk -F/ -v OFS=. '{f=$NF;v=$(NF-1);a=$(NF-2); NF-=3; sub(/^[^[:alnum:]]+/, ""); 
  printf "-filename: %s\n-version: %s\n-artifact: %s\n-group: %s\n\n", f, v, a, $0 }' file
-filename: BillP-3.5.11.jar
-version: 3.5.11
-artifact: BillP
-group: com.eric.ics

-filename: BillP-3.5.11.jar
-version: 3.5.11
-artifact: BillP
-group: com.eric.some.other.pkg

cat file
./com/eric/ics/BillP/3.5.11/BillP-3.5.11.jar
./com/eric/some/other/pkg/BillP/3.5.11/BillP-3.5.11.jar

编辑:使用以下参数调用辅助脚本:

awk -F/ -v OFS=. '{f=$NF;v=$(NF-1);a=$(NF-2); NF-=3; sub(/^[^[:alnum:]]+/, ""); 
  system("./script.sh " f " " v " " a " " $0) }' file
使用:


我首先想到了Regex,但我使用这样的Regex的问题是它们是位置相关的,正如我所说的,子文件夹的数量可以在实际文件名之前更改。这个脚本解释了为什么我自己无法找到它。:)但是,一旦提取了这些参数,是否有一种简单的方法来调用辅助脚本?我希望能在awk内完成,但我找不到任何允许我这么做的东西。否则,我想我只能通过管道连接到脚本。是的,awk也可以调用您的辅助脚本。
system
getline
都支持调用外部命令。更新了答案以显示如何使用这些参数调用另一个脚本。您还可以将输出传递到
read
。只是,这有点棘手
echo a b c | read x y z
不起作用,因为
read x y z
发生在子shell中。你需要像读x y z这样的东西谢谢你的提示,阿努巴瓦。我不知怎么地习惯了这些
好的解决方案。绝对没有那么优雅,但是非常简单和直接。有时候接吻是最好的方式。这是一个非常艰难的决定,哪一种解决方案是正确的。anubhava解决方案使用awk(这是我最初的问题所要求的),但我必须特别感谢HansKluder提供了一个简单(尽管没有那么优雅)的直接解决方案。吻
#!/usr/bin/env perl    
use strict; use warnings;

while (<DATA>) {
    chomp;
    my @list = split /\//;
    print map { $_ . "\t" . pop(@list) . "\n" }
        qw/-filename: -version: -artifact:/;
    print "-group:\t\t", join(".", @list[1..$#list]), "\n\n";
}

__DATA__
./com/eric/ics/ccc/BillP/3.5.11/BillP-3.5.11.jar
./com/eric/ics/BillP/3.5.11/BillP-3.5.11.jar
./com/eric/ics/xxx/yyy/BillP/3.5.11/BillP-3.5.11.jar
-filename:      BillP-3.5.11.jar
-version:       3.5.11
-artifact:      BillP
-group:         com.eric.ics.ccc

-filename:      BillP-3.5.11.jar
-version:       3.5.11
-artifact:      BillP
-group:         com.eric.ics

-filename:      BillP-3.5.11.jar
-version:       3.5.11
-artifact:      BillP
-group:         com.eric.ics.xxx.yyy