Search for files with spaces after processing file names in CentOS
In Linux, when there is a space in the file name, how can I find or confirm that there is a space in the file name? How can we replace and process these spaces in batches?
Method 1: Enter the file name and use the Tab key. If visible characters such as \ appear after the Tab key, the file name contains spaces. Of course, this method has many drawbacks. For example, it is inefficient and cannot be searched in batches. This method is more effective only when you suspect that a file name has spaces. In addition, you cannot find the file name that contains spaces in the middle of the file. The test is as follows:
[root@DB-Server kerry]# cat >"test.txt "
it is only for test!
[1]+ Stopped cat > "test.txt "
[root@DB-Server kerry]# cat >"tes t.txt"
it is only for test too!
[2]+ Stopped cat > "tes t.txt"
[root@DB-Server kerry]# ls test.txt
ls: test.txt: No such file or directory
[root@DB-Server kerry]# ls test
test~ test1.py test.py test.sh test.txt
[root@DB-Server kerry]# ls test.txt\ \ \ \
test.txt
[root@DB-Server kerry]# ls tes
test~ test1.py test.py test.sh tes t.txt test.txt
Method 2: run the find command to find the file with spaces in the file name.
[Root @ DB-Server kerry] # find.-type f-name "**"-print
./Test.txt
./Tes t.txt
So how can we replace these spaces? The following script can replace the space in the middle of the file, but can only replace the space in the middle of the file, and cannot replace the space behind the file name. The test is as follows:
find . -type f -name "* *" -print |
while read name; do
na=$(echo $name | tr ' ''_')
if [[ $name != $na ]]; then
mv "$name""$na"
fi
done
The above script can only replace spaces in the file name with underscores. So how can we solve the problem of space after a file name? It can be implemented using other shell scripts, as shown below:
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"test.txt "
12
[root@DB-Server kerry]# cat >"tes t.txt"
12
[root@DB-Server kerry]# find . -type f -name "* *" -print
./test.txt
./tes t.txt
[root@DB-Server kerry]# for file in *; do mv "$file" `echo $file | tr ' ' '_'` ; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
[root@DB-Server kerry]# ls -lrt
total 8
-rw-r--r-- 1 root root 0 Nov 13 10:04 test.txt
-rw-r--r-- 1 root root 0 Nov 13 10:04 tes_t.txt
As shown above, although the spaces in the middle of the file name are replaced with underscores, the spaces behind them are not replaced with underscores, but are directly truncated. Why? The same is true with the sed command below.
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"test.txt "
12
[root@DB-Server kerry]# cat >"tes t.txt"
12
[root@DB-Server kerry]# find . -type f -name "* *" -print
./test.txt
./tes t.txt
[root@DB-Server kerry]# for i in *' '*; do mv "$i" `echo $i | sed -e 's/ /_/g'`; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
[root@DB-Server kerry]# ls -lrt
total 8
-rw-r--r-- 1 root root 0 Nov 13 09:29 test.txt
-rw-r--r-- 1 root root 0 Nov 13 09:29 tes_t.txt
[root@DB-Server kerry]#
[root@DB-Server kerry]#
In fact, this is because the file name to be read is different from $ file, $ file does not recognize the space behind the file name, and "$ file" will fail the space behind the file name. Therefore, the above script is just a coincidence.
[root@DB-Server kerry]# rm -rf *;
[root@DB-Server kerry]# cat >"test.txt "
123
[root@DB-Server kerry]# for file in *; do echo "$file"; echo "$file" | wc -m ; done;
test.txt
13
[root@DB-Server kerry]# for file in *; do echo $file; echo $file | wc -m ; done;
test.txt
9
[root@DB-Server kerry]#
Therefore, the correct command to replace spaces should be as follows:
Solution 1:
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"test.txt "
123456
[root@DB-Server kerry]# find . -type f -name "* *" -print
./test.txt
[root@DB-Server kerry]# for file in *; do mv "$file" `echo "$file" | tr ' ' '\n'` ; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
[root@DB-Server kerry]# ls test.txt
test.txt
[root@DB-Server kerry]#
Solution 2:
[root@DB-Server kerry]#
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"test.txt "
123456
[root@DB-Server kerry]# for file in *' '*; do mv "$file" `echo "$file" | sed -e 's/ /n/g'`; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
However, when the file name contains spaces, neither of the above two scripts can solve the problem perfectly. As follows:
[root@DB-Server kerry]#
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"tes t.txt"
123456
[root@DB-Server kerry]# for file in *; do mv "$file" `echo "$file" | tr ' ' '_'` ; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
[root@DB-Server kerry]# ls -lrt
total 8
-rw-r--r-- 1 root root 7 Nov 13 16:00 tes_t.txt
[root@DB-Server kerry]#
[root@DB-Server kerry]# rm -rf *
[root@DB-Server kerry]# cat >"tes t.txt"
123456
[root@DB-Server kerry]# cat >"test.txt "
654321
[root@DB-Server kerry]# find . -type f -name "* *" -print
./test.txt
./tes t.txt
[root@DB-Server kerry]# for file in *; do mv "$file" `echo "$file" | tr ' ' '_'` ; done
[root@DB-Server kerry]# find . -type f -name "* *" -print
[root@DB-Server kerry]# ls -lrt
total 12
-rw-r--r-- 1 root root 0 Nov 13 15:59 tes_t.txt
-rw-r--r-- 1 root root 7 Nov 13 15:59 test.txt____
Of course, none of the above scripts can be processed together in these two special cases. As shown above, the following spaces are replaced with underscores. This is not what we want, but the top two types of scripts can solve these two problems by mistake. Of course, the premise is that you know exactly what it is!