Bash Readlink-如何裁剪完整路径?

Bash Readlink-如何裁剪完整路径?,bash,readlink,Bash,Readlink,我使用readlink查找文件的完整路径: cek=$(readlink -f "$1") mkdir -p "$ydk$cek" mv "$1" "$ydk/$cek/$ydkfile" 但是readlink-f“$1”提供了完整的路径。如何裁剪整个路径 例如: /home/test/test/2014/10/13/log.file 但我只需要 /test/2014/10/13/ 我怎么做 从多条评论来看: 输出应该是readlink返回的完整路径的最后四个

我使用
readlink
查找文件的完整路径:

  cek=$(readlink -f "$1")
  mkdir -p  "$ydk$cek"
  mv "$1" "$ydk/$cek/$ydkfile"  
但是
readlink-f“$1”
提供了完整的路径。如何裁剪整个路径

例如:

  /home/test/test/2014/10/13/log.file
但我只需要

  /test/2014/10/13/
我怎么做


从多条评论来看:

  • 输出应该是
    readlink
    返回的完整路径的最后四个目录组件
鉴于:

full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
输出应为:

test/2014/08/29

(不要在路径修剪代码中假设今天的日期。)

您真的需要删除“/home”吗


仅最后4个目录组件:

last4dirs() { 
    local IFS=/
    local -a components=($1)
    local l=${#components[@]}
    echo "${components[*]:l-5:4}"
}
last4dirs /home/some/where/hidden/test/2014/08/29/sparefile.log

您真的需要删除“/主页”吗


仅最后4个目录组件:

last4dirs() { 
    local IFS=/
    local -a components=($1)
    local l=${#components[@]}
    echo "${components[*]:l-5:4}"
}
last4dirs /home/some/where/hidden/test/2014/08/29/sparefile.log

如果您需要完整路径的最后四个目录组件,并且完整路径中没有换行符,并且如果您有GNU
grep
或支持
-o
的BSD(Mac OS X)
grep
(仅输出匹配的材料),那么这将给出所需的结果:

$ cek="/home/test/test/2014/10/13/log.file"
$ echo "${cek%/*}"
/home/test/test/2014/10/13
$ echo "${cek%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/10/13
$ full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
$ echo "${full_path%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/08/29
$

我需要路径开始
/201[0-9]

/home/bla/bla2/bla3/2014/01/13/13…
⟶ <代码>/2014/01/13/13…

因此,您需要再次使用
grep-o
,从年份模式开始:

echo "${fullpath%/*}" | grep -o -e '/201[0-9]/.*$'
这要简单得多;你甚至不需要扩展正则表达式

如果您在该年之前也需要path元素,那么您需要:

echo "{fullpath%/*}" | grep -o -e '/[^/][^/]*/201[0-9]/.*$'

如果您需要完整路径的最后四个目录组件,并且完整路径中没有换行符,并且如果您有GNU
grep
或支持
-o
的BSD(Mac OS X)
grep
(仅输出匹配的材料),那么这将给出所需的结果:

$ cek="/home/test/test/2014/10/13/log.file"
$ echo "${cek%/*}"
/home/test/test/2014/10/13
$ echo "${cek%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/10/13
$ full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
$ echo "${full_path%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/08/29
$

我需要路径开始
/201[0-9]

/home/bla/bla2/bla3/2014/01/13/13…
⟶ <代码>/2014/01/13/13…

因此,您需要再次使用
grep-o
,从年份模式开始:

echo "${fullpath%/*}" | grep -o -e '/201[0-9]/.*$'
这要简单得多;你甚至不需要扩展正则表达式

如果您在该年之前也需要path元素,那么您需要:

echo "{fullpath%/*}" | grep -o -e '/[^/][^/]*/201[0-9]/.*$'

也许这可以帮助您:您只需要删除
/home/test
,或者这里有一些您忘记告诉的其他逻辑?您如何确定从名称的开头裁剪什么?是
$ydk
$HOME
中的值还是其他值?我无法确定启动方式。我只知道最后3或4个文件夹的名称,我需要裁剪最后3或4个文件夹的方式。如果你不知道,我们也不知道。如果您不知道是否需要3个或4个组件,我们如何判断是否保留3个或4个组件?决定使用3个组件而不是4个组件的标准是什么?也许这可以帮助您:您只需删除
/home/test
,或者这里有一些其他逻辑,您忘记告诉了?如何确定从名称开始剪切的内容?是
$ydk
$HOME
中的值还是其他值?我无法确定启动方式。我只知道最后3或4个文件夹的名称,我需要裁剪最后3或4个文件夹的方式。如果你不知道,我们也不知道。如果您不知道是否需要3个或4个组件,我们如何判断是否保留3个或4个组件?决定3个组件而不是4个组件的标准是什么?在我看来,
${dir#ydk}
更像是后面的OP。虽然不是很清楚,但是前面的
/home/test
似乎缺少所需的输出(输出中只有一个
/test
),最后的
log.file
。这是一个路径片段,但切割路径前端的依据尚不清楚。不清楚您为什么不使用
${cek%/*}
而不是
$(dirname“$cek”)
。谢谢您的帮助。如果我有一个以上的主文件夹,有时指一个主文件夹或测试文件夹,有时指2-3个文件夹。我如何才能裁剪/test/2014/10/13/?“仅表示最后3或4个文件夹方式。@volkanasr:您必须告诉我们哪个变量包含必须删除的前缀(
/home/test
)。这是很平常的:
${dir#$variable_holding_prefix_to_be_remove}
@EtanReisner:我没有在“
”${var%/*}”中擦鼻子$(dirname“$var”)
issue;这就是词汇操作和“语义”操作之间的区别。变量替换是一种纯文本操作,而
dirname
使用语义。在这种情况下,
readlink
的输出(显然)是一个完整路径,而不是一个相对路径或简单的重命名-这在一般情况下是不能保证的(
。/../other/directory/hierarchy/target file
readlink
的可能输出;您需要使用
realpath()的
realpath
命令
函数获取绝对名称)。在我看来,${dir#$ydk}更像是后面的OP。虽然不是很清楚,但是前面的
/home/test
似乎缺少所需的输出(输出中只有一个
/test
),最后的
log.file
。这是一个路径片段,但切割路径前端的依据尚不清楚。不清楚您为什么不使用
${cek%/*}
而不是
$(dirname“$cek”)
。谢谢您的帮助。如果我有一个以上的主文件夹,有时指一个主文件夹或测试文件夹,有时指2-3个文件夹。我如何才能裁剪/test/2014/10/13/?“仅表示最后3或4个文件夹方式。@volkanasr:您必须告诉我们哪个变量包含必须删除的前缀(
/home/test
)。这是很平常的:
${dir#$variable_holding_prefix_to_be_remove}
@EtanReisner:我没有在“
”${var%/*}”中擦鼻子$(dirname“$var”)
issue;这就是词汇操作和“语义”操作之间的区别。变量替换是一种纯文本操作,而
dirname
使用语义。在这里