我正在尝试编写一个shell脚本,该脚本需要转换以下形式的输入:
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
进入:
baz-qux
quz
foo
即在'/'上分割,删除前2个句段,删除'.txt',然后用剩余的斜杠代替连字符。
使用tr替换似乎很简单:
paths=$(cat <<- EOF
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
EOF
)
echo $paths | tr '/' '-' | tr '.txt' ' '
我尝试了各种形式的
cut -d '/' -f x
要获得必要的细分,但很快就会结束。
我是一个红宝石家伙,所以很想伸手拿锤子,只用红宝石:
lines.each { |s| s.split('/')[2..-1].join('-').split('.')[0] }
但是为这一操作部署红宝石似乎是过大了。而且我还是想提高我的shell技能,所以想知道是否有人建议在shell中使用更优雅的方式?
感谢您的帮助
答案 0 :(得分:6)
可以使用bash
parameter expansions完成
for name in foo/bar/baz/qux.txt bar/baz/quz.txt baz/quz/foo.txt; do
new=${name#*/} # drop the shortest prefix match for */, thus everything up to first /
new=${new#*/} # repeat, dropping the second segment
new=${new%.txt} # drop shortest suffix match for .txt
new=${new//\//-} # convert any remaining slashes
echo "$new"
done
礼物:
baz-qux
quz
foo
这些都是bash
Shell内置结构,因此不需要诸如cut
,sed
或tr
之类的外部进程。
答案 1 :(得分:1)
您可以尝试执行以下操作:cut -d/ -f3- | cut -d. -f1 | tr / -
说明:
cut -d/ -f3-
-在'/'上分割,并保留第三个字段及其后的所有内容(baz/qux.txt
)cut -d. -f1
-在'。'上分割,保留第一个值(删除文件扩展名)(baz/qux
)tr / -
-将所有剩余的“ /”转换为“-”。
(baz-qux
)答案 2 :(得分:1)
您可以用一个sed
命令完成所有操作
sed -E 's|([^/]*/){,2}||; s|/|-|g; s|\.txt$||' file
将\.txt$
替换为\.[^.]$
,以删除所有扩展名,而不是仅删除.txt
。
答案 3 :(得分:1)
尝试Perl
$ cat mark_smith.txt
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
$ perl -F"/" -lane ' @a=@F[2..$#F]; @b=map{s/.txt//g;$_} @a; print join("-",@b) ' mark_smith.txt
baz-qux
quz
foo
$
答案 4 :(得分:1)
假设.
仅在文件名中
$ awk -F[/.] '{n=NF; p=$(n-1)} n>4{p=$(n-2)"-"p} {print p}' file
baz-qux
quz
foo
答案 5 :(得分:1)
awk '{gsub(/^.{8}|.txt$/,"")sub(/\//,"-")}1' file
baz-qux
quz
foo