How can I tell bash to correctly screen extended strings?

Suppose I have a directory containing files

foo bar.txt foo baz.txt 

(each with a space between 'o' and 'b'). Suppose I would like to do this:

 for f in *.txt; do mv ${f} `basename ${f} .txt`; done 

This fails because bash extends *.txt to

 foo bar.txt foo baz.txt 

instead

 foo\ bar.txt foo\ baz.txt 

i.e. properly shielded, as if I were using tabs.

How can I get bash to properly exit its output?

+4
source share
2 answers

you put quotes in your variables. this way you save space. In addition, there is no need to use the external basename command. the shell can do it for you. (if you use bash)

 for file in *.txt do mv "$file" "${file%.txt}" done 
+4
source

Or, if this is a single operation, you can use vim:

 > ls -al foo bar.txt foo baz.txt 

Open vim and run:

 :r!ls *.txt 

This downloads the files and then does:

 :%s/\(\(.*\)\.txt\)/mv "\1" "\2"/gc 

This will replace the lines as follows:

 mv "foo bar.txt" "foo bar" mv "foo baz.txt" "foo baz" 

Highlight everything with Ctrl-v down, then type : and enter the remainder of this command:

 :'<,'>!bash 

This will execute the highlighted commands in bash. Exit vim and check your directory:

 > ls foo bar foo baz 
+2
source

Source: https://habr.com/ru/post/1300410/


All Articles