Answers:
怎么样:
for f in *; do mv "$f" "$f"_$(wc -l < "$f"); done
例如:
$ wc -l *
10 file1
40 file2
100 file3
$ ls
file1_10 file2_40 file3_100
如果您想保留扩展名(如果有),请改用以下方法:
for f in *; do
ext="";
[[ $f =~ \. ]] && ext="."${f#*.};
mv "$f" "${f%%.*}"_$(wc -l < "$f")$ext;
done
_
。至于剧本,什么剧本?那应该从命令行运行,不需要脚本。如果只希望它与某些文件匹配,则将更改in *
为例如in *txt
。
wc -l < $f
代替grep会更容易理解(也许执行起来更好,但我没有检查过)。
wc
,我想展示一种不同的方法。但是,还可以。
您可以尝试以下一种衬垫:
find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
这将在当前工作目录(find . -maxdepth 1 -type f
)中找到所有文件
然后,我们在找到的文件上运行shell实例,以重命名文件以追加行数。
范例:
$ ls
bar.txt spam.txt foo.txt
$ find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
$ ls
bar.txt.12 foo.txt.24 spam.txt.7
保留扩展名(如果存在)的另一种方法是rename
:
for f in *; do rename -n "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
如果结果是预期的,请删除该-n
选项:
for f in *; do rename "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
rename
伟大=)+1
(\.?[^\.]+)
。
(\.?[^\.]+)
也不行,因为它只能匹配第二个点,并且不匹配具有连续点或以点结尾的文件名。这不是一个容易解决的难题,唯一的方法似乎是进行两次替换。
.
在字符类中转义。
使用find
:
find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "$f"_$(grep -c . "$f"); done
例
% wc -l *
3 doit
5 foo
% find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "$f"_$(grep -c . "$f"); done
% wc -l *
3 doit_3
5 foo_5
-name "*"
呢?剩下的测试?;)
该脚本包含以下几种情况:单点和扩展名(file.txt),多个点和扩展名(file.1.txt),连续点(file..foobar.txt)和文件名中的点(file。或文件..)。
剧本
#!/bin/bash
# Author: Serg Kolo
# Date: June 25,2015
# Description: script to rename files to file_numlines
# written for http://askubuntu.com/q/640430/295286
# Where are the files ?
WORKINGDIR=/home/xieerqi/substitutions
# Where do you want them to go ?
OUTPUTDIR=/home/xieerqi/substitutions/output
for file in $WORKINGDIR/* ;do
FLAG=0
EXT=$(printf "%s" "$file" | awk -F'.' '{printf "%s",$NF }' ) # extension, last field of dot-separated string
# EXT="${file##*.}" # Helio's advice is to use parameter expansion, but I dont know how to use it
if [ -z $EXT ]; then # we have a dot at the end case file. or something
# so we gotta change extension and filename
EXT=""
FILENAME=$(printf "%s" "$file" | awk -F '/' '{ print $NF}' )
# set flag for deciding how to rename
FLAG=1
else
FILENAME=$( printf "%s" "$file" | awk -F '/' -v var=$EXT '{gsub("."var,"");print $NF}' ) # filename, without path, lst in
fi
NUMLINES=$(wc -l "$file" | awk '{print $1}') # line count
if [ $FLAG -eq 0 ];then
echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT"
# cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT" # uncomment when necessary
else
echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT"
# cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT" # uncomment when necessary
fi
#printf "\n"
done
剧本在行动
$./renamer.sh
/home/xieerqi/substitutions/file. renamed as /home/xieerqi/substitutions/output/file._0
/home/xieerqi/substitutions/file.. renamed as /home/xieerqi/substitutions/output/file.._0
/home/xieerqi/substitutions/file.1.jpg renamed as /home/xieerqi/substitutions/output/file.1_3.jpg
/home/xieerqi/substitutions/file.1.test.jpg renamed as /home/xieerqi/substitutions/output/file.1.test_3.jpg
/home/xieerqi/substitutions/file.1.test.txt renamed as /home/xieerqi/substitutions/output/file.1.test_2.txt
/home/xieerqi/substitutions/file.1.txt renamed as /home/xieerqi/substitutions/output/file.1_2.txt
/home/xieerqi/substitutions/file.2.jpg renamed as /home/xieerqi/substitutions/output/file.2_3.jpg
/home/xieerqi/substitutions/file.2.test.jpg renamed as /home/xieerqi/substitutions/output/file.2.test_3.jpg
/home/xieerqi/substitutions/file.2.test.txt renamed as /home/xieerqi/substitutions/output/file.2.test_2.txt
/home/xieerqi/substitutions/file.2.txt renamed as /home/xieerqi/substitutions/output/file.2_2.txt
/home/xieerqi/substitutions/foo..bar.txt renamed as /home/xieerqi/substitutions/output/foo..bar_4.txt
请注意,文件中没有行。和file ..,因此行数为0
特别感谢Terdon和Helio审核了脚本并提出了建议的修改
@helio在聊天中开发的另一种bash方式:
for file in *
do
echo "$file"
[[ -f "$file" ]] || continue
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done
怪异的单头家伙,头顶发育不良((.*)(\.[^.]+)$
)应该只匹配适当的扩展名(.foo
,而不是..
)。如果没有扩展名,则该BASH_REMATCH
数组将为空。我们可以通过使用filename的默认值${BASH_REMATCH[1]:-$file}
并按原样使用扩展名来利用这一点。
要处理点文件,可以find
按照terdon和Helio的建议使用。
find -maxdepth 1 -type f -printf '%P\0' |
while IFS= read -r -d '' file
do
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done