我有一个脚本,可以列出符合特定条件的一组文件。它仅输出文件名,并且有一堆不必要的文本。
示例字符串为:
[gg]_Magi_-_13_[DB38165F].mkv
我想在输出中实现的是:
[gg]_Magi_-_13
我已经能够替换下划线,但无法成功修剪 [CRC32].mkv。此外,我还限制了字符数,如果字符数超过 28 个字符,则在末尾添加省略号,但即使字符数不超过 28 个字符,它仍会在末尾附加省略号。
代码如下:
print substr( $0, 0, 28 )"[…]"}
对于这些问题的帮助将不胜感激。
答案1
虽然awk
、sed
和 公司 各有优点,但它们并不是必需的。您只需使用bash
字符串操作和模式匹配即可轻松实现您要求的一切。假设您已将文件名分配给$name
:
name="${name%_\[*\].*}"
将从中截断文件类型和括号内的 CRC $name
。如果您需要 100% 确保只截断 CRC,则可以使用扩展正则表达式代替上述内容:
[[ $name =~ (.*)_\[[[:xdigit:]]{8}\]\..*$ ]] && name="${BASH_REMATCH[1]}"
然后通过以下方式截断长度超过 28 个字符的名称:
(( ${#name} > 28 )) && name="${name::27}…"
– 总共两行bash
(不包括逻辑、循环或其他,将文件名放入 var,当然还有输出代码),没有外部代码。主要优点是代码速度极快,因为 shell 永远不需要启动任何外部二进制文件。
答案2
我认为满足所有条件的最短解决方案就是这个
awk '{
if (match($0, "^(.*)_[^_]+$", a)) {
print substr(a[1], 1, 27) (length(a[1]) > 27 ? "..." : "")
}
}'
答案3
sed -e 's/_\[.*\.mkv//' -e 's/^\(.\{28\}\).*/\1.../' file.txt
第一位去掉_[blah].mkv
,第二位打印前 28 个字符,并将 放在...
末尾 - 但如果字符串少于 28 个字符,它只会打印去掉的文件名,而不会添加省略号。
如果文件的扩展名不总是 *.mkv,您可以使用这个(在 sed 中,$
表示“到行尾”):
sed -e 's/_\[.*$//' -e 's/^\(.\{28\}\).*/\1.../' file.txt
答案4
这不是最干净的解决方案,但你可以这样做:
echo "[gg]_Magi_-_13_[DB38165F].mkv" | awk -F '_' '{print $1"_"$2"_"$3"_"$4}'
编辑:嗯,删除这个答案。它不会给你省略号。