Cut a field in a string with bash
5,306
Solution 1
You should be using dirname
and basename
instead of these tricks with rev and cut
declare -l file_lower # anything assigned to this varname will be lower-cased
find $1 -type f | while read -r file
do
file_lower=$(basename "$file")
dir=$(dirname "$file")
mv "$file" "$dir/$file_lower"
done
find $1 -type d | sort -r | while read -r file
do
file_lower=$(basename "$file")
dir=$(dirname "$file")
mv "$file" "$dir/$file_lower"
done
Solution 2
cut -d/ -f 2-
Cut supports ranges for its offset parameter, e.g. -f 2-
, -c -2
, -b 1-3
Solution 3
On a GNU system:
find . -depth -name '*[[:upper:]]*' -printf '%h\0%f\0' |
awk -v RS='\0' '{getline f; printf "%s\0%s\0", $0"/"f, $0"/"tolower(f)}' |
xargs -r0n2 echo mv
(remove echo
when happy).
Or if you can use zsh
:
autoload zmv
zmv -n -wQ '**/*(D)' '$1${(L)2}'
(remove -n
when happy)
Related videos on Youtube
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Author by
Admin
Updated on September 18, 2022Comments
-
Admin almost 2 years
I need to lower all upper-cases of file and folder names from a path, recursively inside other folders found; I need to do that with a bash script.
Here my code:
for file in $(find $1 -type f) do tmp=$(echo $file | rev | cut -d/ -f1 | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) tmp2=$(echo $file | rev | cut ????) tmp=$tmp$tmp2 mv $file $(echo $tmp | rev) done for file in $(find $1 -type d | sort -r) do tmp=$(echo $file | rev | cut -d/ -f1 | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) tmp2=$(echo $file | rev | cut) tmp=$tmp$tmp2 mv $file $(echo $tmp | rev) done
The problem is at line 4, [
tmp2=$(echo $file | rev | cut ????)
] I don't know how I can select all the fields delimited with/
after the first field.With line 3 I can isolate the file name and with the
tr
command modify all upper-cases, but then comes the trouble. Same for folders t the second 'for' construct. -
Stéphane Chazelas over 10 yearsThat assumes file names don't contain newline characters and don't end in space or tab characters. It interprets the first argument as a list of file patterns.
sort -r
doesn't do what you (and the OP) think it does as there are several characters that sort before/
(you want-depth
here).