Renaming files to add a suffix
I need a command to rename all files in the current working directory, in a way that the new filename will be the same as the old, but including a suffix corresponding to the number of lines of the original files (e.g. if the file f
has 10 lines then it should be renamed to f_10
).
Here's my (non-working) attempt:
linenum=$(wc -l); find * -type f | grep -v sh | rename 's/^/ec/'*
Solution 1:
How about:
for f in *; do mv "$f" "$f"_$(wc -l < "$f"); done
For example:
$ wc -l *
10 file1
40 file2
100 file3
$ ls
file1_10 file2_40 file3_100
If you want to keep extensions (if present), use this instead:
for f in *; do
ext="";
[[ $f =~ \. ]] && ext="."${f#*.};
mv "$f" "${f%%.*}"_$(wc -l < "$f")$ext;
done
Solution 2:
You can try this one liner:
find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
This will find all files in the current working directory (
find . -maxdepth 1 -type f
)Then we are running a shell instance over the files found to rename the files to append the number of lines.
Example :
$ 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
Solution 3:
Another way which preserves the extension (if present) using rename
:
for f in *; do rename -n "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
If the result is the expected one, remove the -n
option:
for f in *; do rename "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
Solution 4:
Using find
:
find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "$f"_$(grep -c . "$f"); done
Example
% 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
Solution 5:
Just for fun and giggles a solution with rename
. Since rename
is a Perl tool that accepts an arbitrary string that is eval'd, you can do all sorts of shenanigans. A solution that seems to work is the following:
rename 's/.*/open(my $f, "<", $_);my $c=()=<$f>;$_."_".$c/e' *