scotty030253 Asked: 2024-03-11 07:59:15 +0800 CST2024-03-11 07:59:15 +0800 CST 2024-03-11 07:59:15 +0800 CST 从字符串中剪切文件夹名称 772 如何提取test以下字符串命名的文件夹? TRUE|/home/linux/test|(null)| command-line 5 个回答 Voted Artur Meinild 2024-03-11T21:13:53+08:002024-03-11T21:13:53+08:00 Bash 有一种非常简单的方法来将路径元素(只要您的路径定义为变量)与参数扩展相匹配。 使用该${parameter##word}构造,您可以从行的开头开始搜索,并删除直到最后一个匹配项为止的所有内容。对于路径,这将删除除最后一个目录之外的所有内容,如下所示: path='/path/to/my/stuff'; echo ${path##*/} 输出: stuff |(null)|但就你而言,你仍然需要摆脱最后一部分。在这种特殊情况下,您可以进行双参数扩展,如下所示: path='TRUE|/home/linux/test|(null)|'; path=${path##*/}; echo ${path%%|*} 输出: test 因此,在这种情况下,您首先从头到尾匹配/(使用${path##*/}),然后从尾到最后匹配|(使用${path%%|*})。 通过这种方式,您可以仅使用 Bash 内置功能来执行大量字符串操作。 Pacopenguin 2024-03-11T23:25:42+08:002024-03-11T23:25:42+08:00 这里已经有两个可行的解决方案,但我只想指出以下方法,它可能更多地映射到命令式思维方式。 echo 'TRUE|/home/linux/test|(null)|' | awk -F '|' '{print $2}' | xargs basename 从概念上讲,我们 1) 获取输入的第二个元素,2) 获取该路径的基本名称。 awk -F '|' '{print $2}'对字符进行拆分|,并给出第二个元素,即/home/linux/test. 然后,您需要test从给定路径中提取内容,这就是该basename命令的作用。从美学角度来看,附加内容xargs很烦人,但这是必要的,因为(据我所知)该basename命令无法从stdin. 正如用户@Ray 在他们的评论中指出的那样,在同一解决方案中cut也可以正常工作。awk Best Answer stumblebee 2024-03-11T09:39:07+08:002024-03-11T09:39:07+08:00 如果您想为您的作业获得“额外学分”,那么使用awk echo 'TRUE|/home/linux/test|(null)|' | awk -F '[|/]' '{print $5}' 该awk选项-F定义字段分隔符。当用括号括起来时,[|/]将|和定义/为字段分隔符。那么"test"第五个参数就是'{print $5}' Zanna 2024-03-12T13:57:43+08:002024-03-12T13:57:43+08:00 哦,好吧,这是一个sed答案 $ echo 'TRUE|/home/linux/test|(null)|' | sed -r 's#.*/([^|]+)\|.*#\1#' test 解释: -r使用扩展正则表达式 s#...#..#查找并替换用作#替代分隔符/ .*//包含之前的任意数量的任何字符/(消耗所有/s 只留下最后一个后面的内容) ([^|]+)保存一些|以后不用的字符 \|.* |以及它后面的内容(是一个特殊字符,因此被转义 - 在字符类|中不需要)[ ] \1保存的图案 BeastOfCaerbannog 2024-03-11T23:48:19+08:002024-03-11T23:48:19+08:00 从您的问题中并不清楚您是否想要获取绝对路径的第三项或是否想要获取绝对路径的最后一项。 如果您想获取绝对路径的第三项,您还可以使用以下利用trand的命令cut: echo 'TRUE|/home/linux/test|(null)|' | tr '|' '/' | cut -d '/' -f 5 tr '|' '/'转换|为/,然后cut -d '/' -f 5用作/分隔符 ( -d '/') 并输出第 5 个元素 ( -f 5)。 如果你想使用and类似上面的方式获取绝对路径的最后一项,你也可以使用如下命令:trcutrev echo 'TRUE|/home/linux/test|(null)|' | tr '|' '/' | rev | cut -d '/' -f 3 | rev tr '|' '/'转换|为/,然后第一个rev反转字符串, cut -d '/' -f 3用作/分隔符 ( -d '/') 并输出第三个元素 ( -f 3),最后第二个rev再次反转字符串。 参考 man tr man cut man rev
Bash 有一种非常简单的方法来将路径元素(只要您的路径定义为变量)与参数扩展相匹配。
使用该
${parameter##word}
构造,您可以从行的开头开始搜索,并删除直到最后一个匹配项为止的所有内容。对于路径,这将删除除最后一个目录之外的所有内容,如下所示:输出:
|(null)|
但就你而言,你仍然需要摆脱最后一部分。在这种特殊情况下,您可以进行双参数扩展,如下所示:输出:
因此,在这种情况下,您首先从头到尾匹配
/
(使用${path##*/}
),然后从尾到最后匹配|
(使用${path%%|*}
)。通过这种方式,您可以仅使用 Bash 内置功能来执行大量字符串操作。
这里已经有两个可行的解决方案,但我只想指出以下方法,它可能更多地映射到命令式思维方式。
从概念上讲,我们 1) 获取输入的第二个元素,2) 获取该路径的基本名称。
awk -F '|' '{print $2}'
对字符进行拆分|
,并给出第二个元素,即/home/linux/test
. 然后,您需要test
从给定路径中提取内容,这就是该basename
命令的作用。从美学角度来看,附加内容xargs
很烦人,但这是必要的,因为(据我所知)该basename
命令无法从stdin
.正如用户@Ray 在他们的评论中指出的那样,在同一解决方案中
cut
也可以正常工作。awk
如果您想为您的作业获得“额外学分”,那么使用
awk
该
awk
选项-F
定义字段分隔符。当用括号括起来时,[|/]
将|
和定义/
为字段分隔符。那么"test"
第五个参数就是'{print $5}'
哦,好吧,这是一个
sed
答案解释:
-r
使用扩展正则表达式s#...#..#
查找并替换用作#
替代分隔符/
.*/
/
包含之前的任意数量的任何字符/
(消耗所有/
s 只留下最后一个后面的内容)([^|]+)
保存一些|
以后不用的字符\|.*
|
以及它后面的内容(是一个特殊字符,因此被转义 - 在字符类|
中不需要)[
]
\1
保存的图案从您的问题中并不清楚您是否想要获取绝对路径的第三项或是否想要获取绝对路径的最后一项。
如果您想获取绝对路径的第三项,您还可以使用以下利用
tr
and的命令cut
:tr '|' '/'
转换|
为/
,然后cut -d '/' -f 5
用作/
分隔符 (-d '/'
) 并输出第 5 个元素 (-f 5
)。如果你想使用and类似上面的方式获取绝对路径的最后一项,你也可以使用如下命令:
tr
cut
rev
tr '|' '/'
转换|
为/
,然后第一个rev
反转字符串,cut -d '/' -f 3
用作/
分隔符 (-d '/'
) 并输出第三个元素 (-f 3
),最后第二个rev
再次反转字符串。参考
man tr
man cut
man rev