erich hirzenberger
erich hirzenberger

Reputation: 11

find command doesn't work with colon in name

I copied a lot of folders containing mp3/m4a-files to my NAS-music-dir (ext3) without any problems. some foldernames contain ':' (colon), multiple dots (...) and so on. how can I use the find-command for renaming the folders by deleting colons and other unwanted characters? every simple find-command gives my an error:

cd /nas3/Musik
find . -type d -exec grep -H ':' '{}' \+
find: "./Eis_Am_Stiel_Volume_3:_Liebeleien--The_Shirelles": Datei oder Verzeichnis nicht gefunden
find: "./Kicking_Television:_Live_In_Chicago--Wilco": Datei oder Verzeichnis nicht gefunden
find: "./Respect:_A_Century_Of_Women_In_Music--Mary_Wells": Datei oder Verzeichnis nicht gefunden

...

the German term "Datei oder Verzeichnis nicht gefunden" means "Can't find file or folder".

How can I fix that problem? thx a lot!

Upvotes: 0

Views: 1431

Answers (3)

erich hirzenberger
erich hirzenberger

Reputation: 11

I changed to working dir and tried all 6 versions:

Command line scripts - version1 to version 6

find . -type d -name \*:\* # V1
find . -type d | grep ':' #V2
find . -regextype egrep -iregex '.*\:.*' #V3
find . -iname "*:*" #V4
find . -iname "*:*" -print0 | while IFS= read -rd '' file ; do echo "$file" ; done #V5
find . -iname "*:*" -print | while read -r file ; do echo "$file" ; done #V6

Output of V1, V2 (part)

...
./Booom_2005:_The_First--E-Rotic
./Bravo:_The_Hits_2000--Alannah_Myles
./Booom_2006:_The_First--Curse
find: "./Gold:_Greatest_Hits--Boney_M.": Datei oder Verzeichnis nicht gefunden
./Black_Coffee_Chapter_1:_Ambientfunk_a_Mellowmoves--Aromabar
./Beethoven:_Fate--South_German_Philharmonic_Orchestra
./Bravo:_The_Hits_2002_Part_2--Kelly_Osbourne
...

Output of V3, V4, V5, V6 (part)

...
./Booom_2005:_The_First--E-Rotic
./Bravo:_The_Hits_2000--Alannah_Myles
./Booom_2006:_The_First--Curse
./Gold:_Greatest_Hits--Boney_M.
./Black_Coffee_Chapter_1:_Ambientfunk_a_Mellowmoves--Aromabar
./Beethoven:_Fate--South_German_Philharmonic_Orchestra
./Bravo:_The_Hits_2002_Part_2--Kelly_Osbourne
...

As you can see 1 different line in output of V1 and V2 (not so important). So let's go on with 4 command line scripts - based on version 3, 5, 6, 1 first:

find . -regextype egrep -iregex '.*\:.*' |while read -r line; do new=$(echo "$line"|tr -d ':'); echo "$line" --- "$new";mv "$line" "$new"; done #V3
find . -iname "*:*" -print0 |while IFS= read -rd '' line ; do new=$(echo "$line"|tr -d ':'); echo "$line" --- "$new"; mv "$line" "$new" ; done #V5
find . -iname "*:*" -print |while read -r line ; do new=$(echo "$line"|tr -d ':'); echo "$line" --- "$new"; mv "$line" "$new"; done #V6
find . -type d -name \*:\*|while read -r line ; do new=$(echo "$line"|tr -d ':'); echo "$line" --- "$new"; mv "$line" "$new"; done #V1

Output of V3, V5, V6, V1 (part)

...
./Booom_2005:_The_First--E-Rotic --- ./Booom_2005_The_First--E-Rotic
mv: das Verschieben von »./Booom_2005:_The_First--E-Rotic“ nach »./Booom_2005_The_First--E-Rotic“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

./Bravo:_The_Hits_2000--Alannah_Myles --- ./Bravo_The_Hits_2000--Alannah_Myles
mv: das Verschieben von »./Bravo:_The_Hits_2000--Alannah_Myles“ nach »./Bravo_The_Hits_2000--Alannah_Myles/Bravo:_The_Hits_2000--Alannah_Myles“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

./Booom_2006:_The_First--Curse --- ./Booom_2006_The_First--Curse
mv: das Verschieben von »./Booom_2006:_The_First--Curse“ nach »./Booom_2006_The_First--Curse“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

./Gold:_Greatest_Hits--Boney_M. --- ./Gold_Greatest_Hits--Boney_M.
mv: Aufruf von stat für »./Gold:_Greatest_Hits--Boney_M.“ nicht möglich: Datei oder Verzeichnis nicht gefunden

./Black_Coffee_Chapter_1:_Ambientfunk_a_Mellowmoves--Aromabar --- ./Black_Coffee_Chapter_1_Ambientfunk_a_Mellowmoves--Aromabar
mv: das Verschieben von »./Black_Coffee_Chapter_1:_Ambientfunk_a_Mellowmoves--Aromabar“ nach »./Black_Coffee_Chapter_1_Ambientfunk_a_Mellowmoves--Aromabar“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

./Beethoven:_Fate--South_German_Philharmonic_Orchestra --- ./Beethoven_Fate--South_German_Philharmonic_Orchestra
mv: das Verschieben von »./Beethoven:_Fate--South_German_Philharmonic_Orchestra“ nach »./Beethoven_Fate--South_German_Philharmonic_Orchestra“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

./Bravo:_The_Hits_2002_Part_2--Kelly_Osbourne --- ./Bravo_The_Hits_2002_Part_2--Kelly_Osbourne
mv: das Verschieben von »./Bravo:_The_Hits_2002_Part_2--Kelly_Osbourne“ nach »./Bravo_The_Hits_2002_Part_2--Kelly_Osbourne“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

...

Then I tried a command line script - based on version 2

find . -type d | grep ':' |while IFS= read -rd '' line ; do new=$(echo "$line"|tr -d ':'); echo "$line" --- "$new"; mv "$line" "$new" ; done

And got output of V2 (THIS ARE THE ONLY LINES I GOT OF ABOUT 8000 DIRECTORIES)

find: "./Gold:_Greatest_Hits--Boney_M.": Datei oder Verzeichnis nicht gefunden
find: "./Nino_Rota:_Concerto_for_Strings,_\"La_Strada\"_Suite,_Dances_from_\"Il_Gattopardo\"--Riccardo_Muti": Datei oder Verzeichnis nicht gefunden
find: "./38?_Festivalbar_2001_Compilation_Blu--Christina_Aguilera": Datei oder Verzeichnis nicht gefunden
find: "./Gold:_20_Super_Hits--Boney_M.": Datei oder Verzeichnis nicht gefunden
find: "./Who_Is_It?--Ingrid_Laubrock": Datei oder Verzeichnis nicht gefunden
find: "./Let_It_All_Be_Music:_The_Party_Album--Boney_M.": Datei oder Verzeichnis nicht gefunden
find: "./Who_Let_the_Cats_Out?--Mike_Stern": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Who_Is_It?--Ingrid_Laubrock": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Who_Let_the_Cats_Out?--Mike_Stern": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Was_Ist_Passiert?--Pur": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Are_You_Looking_At_Me?--Colin_Hay": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Are_You_Experienced?--Jimi_Hendrix_Experience": Datei oder Verzeichnis nicht gefunden
find: "./tmp2/Whats_Wrong_with_This_Picture?--Van_Morrison": Datei oder Verzeichnis nicht gefunden
find: "./Was_Ist_Passiert?--Pur": Datei oder Verzeichnis nicht gefunden
find: "./Whats_Wrong_with_This_Picture?--Van_Morrison": Datei oder Verzeichnis nicht gefunden

OK, 15 error-lines isn't a lot of errors when checking 8000 directories for ':'. But when I checked the directory names I found all of them have their original names. With other words: plenty of commands with no effect.

Upvotes: 0

Bjorn A.
Bjorn A.

Reputation: 1178

find . -type d -exec grep -H ':' '{}' \+

This command looks weird to me. I use the same construct a lot, but never quote the braces or escape the +. The big question though, is why you want to grep the directory.

Maybe you meant to do this instead?

find . -type d -name \*:\*

or maybe

find . -type d | grep ':' 

Upvotes: 1

hmedia1
hmedia1

Reputation: 6180

Command:

find . -regextype egrep -iregex '.*\:.*'

Alternative:

find . -iname "*:*"

Result:

./Eis_Am_Stiel_Volume_3:_Liebeleien--The_Shirelles
./Kicking_Television:_Live_In_Chicago--Wilco
./Respect:_A_Century_Of_Women_In_Music--Mary_Wells

Comments:

  • When working with find (or any filenames being thrown around the pipeline), the practise of using "<---quotes--->" around any identifier/variable/backreference/string will much more often than not, be helpful.

  • If for some reason you do need to act on a filename sent out from find, using a null separator is much safer:

Example:

find . -iname "*:*" -print0 | while IFS= read -rd '' file ; do echo "$file" ; done

Will work the same as :

find . -iname "*:*" -print | while read -r file ; do echo "$file" ; done

But the first example is much safer:

  • Using -print0 causes find to output null separated files, as opposed to line separated files. You'd be surprised where some oddly named files (especially those extracted from a download / poorly converted / otherwise) contain newline escapes which when placed non-strategically in the pipeline can be really, really bad.

  • The while IFS= (but without a command separator), sets IFS for that command. So you're not going to get any surprises if this environment var gets changed

  • while IFS= read -rd '' varis essentially the "read" compliment to print0 -- If you output null separators, then you also have to read null separators.

Upvotes: 1

Related Questions