使用完整文件路径删除shell脚本子串

时间:2014-10-03 20:14:27

标签: shell

使用底部突出显示的代码,我正在尝试实现以下输出:

/dir/subdir/file1.ext
/dir/subdir/file3.ext

但是,我尝试的所有内容都没有给我预期的结果,而且我总是最终没有被删除或替换。这甚至可以使用这种方法,还是我必须采用像sed这样的东西?

#!/sbin/sh

testvar="/dir/subdir/file1.ext
/dir/subdir/file2.ext
/dir/subdir/file3.ext"

testvar=${testvar/\/dir\/subdir\/file2.ext\n}

echo $testvar

谢谢大家的回复。我已经尝试了所有这些并且没有任何建议成功。唯一对我有用的代码是下面的代码。

testvar=${testvar/?dir?subdir?file2.ext?}

逃避正斜杠'/'对我来说根本不起作用。而且,在使用外卡'?'时做的工作,执行速度很慢。如果没有其他办法,我会继续使用它,但如果还有其他想法,我会很高兴看到它们。再次谢谢。

3 个答案:

答案 0 :(得分:1)

回答修订问题

修订后的问题需要对脚本进行三处更改:

#!/sbin/bash    
testvar="/dir/subdir/file1.ext
/dir/subdir/file2.ext
/dir/subdir/file3.ext"

testvar=${testvar/\/dir\/subdir\/file2.ext?}

echo "$testvar"

此脚本生成输出:

/dir/subdir/file1.ext
/dir/subdir/file3.ext

三个建议的更改是:

  1. 您的脚本使用特定于bash的功能。所以,shebang线应该引用bash。根据系统默认值以及如何调用脚本,这可能不是必需的,但是,当使用特定于bash的功能时,它总是一个好主意。

  2. 在参数展开中,\n需要替换为?。这是因为,正如bash所看到的那样,\n代表两个字符,\n

  3. 要在输出中维护换行符,$testvar必须在双引号内。否则,会发生单词拆分,导致换行符(以及有任何标签符号)用空格替换。

  4. 回答原始问题

    testvar=$'/dir/subdir/file1.ext\n/dir/subdir/file2.ext\n/dir/subdir/file3.ext'
    testvar="${testvar/\/dir\/subdir\/file2.ext?/}"
    echo "$testvar"
    

    这会产生输出:

    /dir/subdir/file1.ext
    /dir/subdir/file3.ext
    

    关键点:

    • 从您想要的输出中,我推断您需要真正的换行符而不是两个字符\n。因此,testvar是使用$'...'

    • 定义的
    • 要使用参数展开删除空白行,必须匹配换行符。这是使用?完成的,因为在bash中,两个字符\n再次与换行符不匹配。

    • 如果您想在回显testvar时保留换行符,则$testvar需要在双引号内。否则,换行符将转换为空格。

答案 1 :(得分:0)

回答修订问题

$ testvar="/dir/subdir/file1.ext
> /dir/subdir/file2.ext
> /dir/subdir/file3.ext"
$ x=${testvar/\/dir\/subdir\/file2.ext
> }
$ echo "$x"
/dir/subdir/file1.ext
/dir/subdir/file3.ext
$

请注意替换中嵌入的换行符。另请注意,Bash在历史记录中没有正确映射(使用Apple的3.2.53(1)和我在Mac OS X 10.9.5上构建的4.3.27(2))。第一行是从历史中获得的。

$ x=${testvar/\/dir\/subdir\/file2.ext; }
$ echo "$x"
/dir/subdir/file1.ext
/dir/subdir/file2.ext
/dir/subdir/file3.ext
$

当然,这在shell脚本中无关紧要。

回答原始问题

首先请注意$testvar不包含任何换行符:

$ testvar="/dir/subdir/file1.ext\n/dir/subdir/file2.ext\n/dir/subdir/file3.ext"
$ printf "%s\n" "$testvar"
/dir/subdir/file1.ext\n/dir/subdir/file2.ext\n/dir/subdir/file3.ext
$

接下来,您需要将反斜杠与双反斜杠匹配,并且需要匹配中间\n之前和之后的/dir/subdir/file2.ext

$ nl="
> "
$ x=${testvar/\\n\/dir\/subdir\/file2.ext\\n/$nl}
$ echo "$x"
/dir/subdir/file1.ext
/dir/subdir/file3.ext
$ printf "%s\n" "$x"
/dir/subdir/file1.ext
/dir/subdir/file3.ext
$

您也可以在没有$nl变量的情况下执行此操作:

$ x=${testvar/\\n\/dir\/subdir\/file2.ext\\n/
> }
$ echo "$x"
/dir/subdir/file1.ext
/dir/subdir/file3.ext
$

答案 2 :(得分:0)

您可以使用${variable##pattern}${variable%%pattern}语法分别删除变量开头或结尾处的内容。

假设我理解了您的要求,您可以使用它来删除所有内容,包括字符串中第一次出现换行符号,以提取第一个和最后一个文件名。

testvar="/dir/subdir/file1.ext
/dir/subdir/file2.ext
/dir/subdir/file3.ext"

# Store a newline inside a variable for convenience.
nl="
"

first="${testvar%%$nl*}"
last="${testvar##*$nl}"

echo "first: $first"
echo "last:  $last"

输出:

first: /dir/subdir/file1.ext
last:  /dir/subdir/file3.ext

您可以在Bash参考手册的3.5.3 Shell Parameter Expansion部分阅读此处使用的语法的详细信息。

相关问题