我有一个以下形式的文件:
XXX XXXX XXX-6VwvOkZvzuI.description
我怎样才能只获取文件名XXX XXXX XXX
?我试过了:
for file in $(ls .d*)
do
fname="${file%*-}"
ext="${filename%.*}"
done
答案1
不要解析ls
(参见例如为什么*不*解析`ls`(以及该怎么做)?)。您遇到的问题是,您的循环变量 ,file
将在文件名全部连接成一个长字符串后获取文件名的值,然后在空格上分割(以及在任何恰好是的分割词之后)通配模式已扩展)。您将获得 filename 循环的三次迭代XXX XXXX XXX-6VwvOkZvzuI.description
,例如,值XXX
、XXXX
和各循环一次XXX-6VwvOkZvzuI.description
。
迭代名称中包含破折号和.description
使用的文件名后缀的所有文件
for name in *-*.description; do ...; done
-
要挑选出in之前的部分$name
,请使用标准参数扩展来删除-
字符串中第一个之后的所有内容:
prefix=${name%%-*}
%%
using和here之间的区别%
在于,使用%%
最长匹配的尾部字符串被删除。如果-
任何名称中碰巧有多个字符,这一点很重要。
然后你的循环就变成了
for name in *-*.description; do
prefix=${name%%-*}
done
文件名后缀已知 ( ),但您可以使用以下命令获取从 到后缀的.description
文件名位-
infix=${name#"$prefix"}
infix=${infix%.description}
最后,使用类似的脚本
#!/bin/sh
suffix=.description
for name in *-*"$suffix"; do
prefix=${name%%-*}
infix=${name#"$prefix"}
infix=${infix%.description}
printf 'prefix="%s", infix="%s", suffix="%s"\n' \
"$prefix" "$infix" "$suffix"
done
你会得到
$ ls
XXX XXXX XXX-6VwvOkZvzuI.description XXX XXXX XXX-6VwvOkZvzuK.description
XXX XXXX XXX-6VwvOkZvzuJ.description script
$ ./script
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuI", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuJ", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuK", suffix=".description"
答案2
尝试这个
$ ls -1
x.sh
XXX XXXX XXX-6VwvOkZvzuI.description
YYY XXXX XXX-6VwvOkZvzuI.description
$ cat x.sh
#!/bin/bash
for file in *.d*
do
fname=${file/-*/}
ext=${file/*-/}
echo fname $fname ext $ext
done
$ ./x.sh
fname XXX XXXX XXX ext 6VwvOkZvzuI.description
fname YYY XXXX XXX ext 6VwvOkZvzuI.description
$
答案3
编辑
我将保留我的答案,但添加 @Kusalananda 答案中的警告:不要解析ls
(参见例如
为什么*不*解析`ls`(以及该怎么做)?)。
我的答案
您可以将 ls 的输出直接通过管道传输到 sed 中,并仅替换连字符 ( -
) 之前的部分:
ls *.d* | sed 's/\(.*\)-.*/\1/'
我尝试使用两个名为的文件:
XXX XXXX XXX-6VwvOkZvzuI (copy).description
XXX XXXX XYZ-6VwvOkZvzuI.description
输出是:
XXX XXXX XXX
XXX XXXX XYZ
sed 命令的工作方式如下:
- 我记得上面使用之间的内容
\(
,\)
在这种情况下,一切都取决于最后的文件名中的连字符(如果您的文件名称中包含后面的连字符,则需要对其进行调整) - 然后替换为记住的内容
\1
- 即仅 XXX 部分
如果需要,您可以将命令的输出放入文件中:
ls *.d* | sed 's/\(.*\)-.*/\1/' > new_file