使用底部突出显示的代码,我正在尝试实现以下输出:
/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?}
逃避正斜杠'/'对我来说根本不起作用。而且,在使用外卡'?'时做的工作,执行速度很慢。如果没有其他办法,我会继续使用它,但如果还有其他想法,我会很高兴看到它们。再次谢谢。
答案 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
三个建议的更改是:
您的脚本使用特定于bash的功能。所以,shebang线应该引用bash。根据系统默认值以及如何调用脚本,这可能不是必需的,但是,当使用特定于bash的功能时,它总是一个好主意。
在参数展开中,\n
需要替换为?
。这是因为,正如bash所看到的那样,\n
代表两个字符,\
和n
。
要在输出中维护换行符,$testvar
必须在双引号内。否则,会发生单词拆分,导致换行符(以及有任何标签符号)用空格替换。
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部分阅读此处使用的语法的详细信息。